使用方式:
使用内联函数优点
使用内联函数的缺点
当调用函数时,有三种向函数传递参数的方式
用&声明引用,必须在声明引用变量时进行初始化
int rat;
int & rodent =rat;
void swapr(int & a,int & b);
void swapr(int & a,int & b)
{
int temp;
temp = a;
a=b;
b=temp;
};
什么时候创建临时变量?
将引用参数声明为常量数据的引用
const free_throws & clone(free_throws & ft)
{
free_throws * pt;
*pt=ft;
return *pt;
}
free_throws & jolly=clone(three);
free_throws(three)=four;将值赋给原型中的参数。对于带参数列表的函数,必须从右向左添加默认值。也就是说要为某个参数设置默认值,则必须为它右边的所有参数提供默认值
int harpo(int n,int m=4,int j=6); // VALID
int chico(int n,int m=6,int j); // INVALID
函数重载指有多个同名函数,但函数的参数列表也称为函数特征标不同:
何时使用函数重载?
使用泛型来定义函数称作模板,在需要多个将同一种算法用于不同类型的函数时,使用模板。
template <typename AnType>
// template <class AnType>
void Swap(AnyType &a,AnType &b)
{
AnyType temp;
temp a;
a=b;
b=temp;
};
具体化由于常规模板,而非模板函数优于具体化和常规模板
//用于交换job结构的的非模板函数
void Swap(job &,job &);
//函数模板
template<typename T>
void Swap(T &,T &);
//具体化
template <> void Swap<job>(job &,job&);//<job> 是可选的
编译器使用模板为特定类型生成函数定义时,得到的是模板实例。
警告:试图在同一个文件(或转换单元)中使用用一种类型的显示实例和现实具体化将出错
隐式实例化:模板并非函数定义,但是用int的模板实例是函数定义,这种实例化方式被称为隐式实例化
显示实例化:声明所需的种类——用<>符号指示类型,并在声明前加上关键字templatetemplate void Swape<int>(int,int);
template <class T>
T Add(T a,T b)
{
return a+b;
};
int m=6;
double x=10.2;
cout<<Add<double>(x,m)<<endl;
//通过Add<double>(x,m),可强制为double类型实例化,并将参数m强制转换为double类型
显示具体化:显示具体化声明在关键字template后包含<>,而显示实例化没有。template <> void Swape<int>(int &,int &);//<int>可选
策略:
1. 创建候选参数列表
2. 使用候选函数列表创建可行函数列表
3. 确定是否有最佳的可行函数。如果有,则使用它,否则该函数调用出错
1. 完全匹配,但常规函数优于模板
2. 提升转换(char和short自动转换为int,float自动转换为double)
3. 标准转换(int转换char,long转换double)
4. 用户定义的转换,如类声明中定义的转换
完全匹配允许的无关紧要转换
| 从实参 | 到形参 |
|---|---|
| Type | Type& |
| Type& | Type |
| Type[] | * Type |
| Type(argument-list) | Type(*)(argument-list) |
| Type | const Type |
| Type | volatile Type |
| Type* | const Type |
| Type* | volatile Type * |
最匹配规则
template<class T1,class T2>
void ft(T1 x,T1 y)
{
//?type? xpy=x+y;
decltype(x+y) xpy=x+y;
};
decltype(expression) var为确定类型,编译器必须遍历一个核对表
long indeed(int)
decltype (indeed(3)) m;//m is type int
// 编译器通过查看函数的原型来获得返回类型,而无需实际调用函数
(expression)double xy=4.4;decltype((xy)) r2=xx;//r2 is double &template<class T2,class T2>
?type? gt(T1 x,T2 y)
{
return x+y;
}
//结合auto h(int x,float y) -> double语法
//-> double 被称为后置返回类型
//auto是一个占位符,表示后置返回类型提供的类型
template<class T2,class T2>
auto gt(T1 x,T2 y) -> decltype(x+y)
{
return x+y;
}
[左值]:左值参数是可被引用的数据对象,例如,变量、数组元素、结构成员、引用和解除引用的指针都是左值。非左值包括字面常量(用引号括起的字符串除外,它们由其他地址表示)和包含多项的表达式。