函数重载和函数模板
1.函数重载
函数重载(函数多态)能让程序使用多个同名的函数。函数重载的关键时函数的参数列表(函数特征标)。
如果两个函数的参数数目和类型相同,同时参数的排列顺序也相同,则它们的参数列表相同。
注:编译器在检查函数特征标时,将类型引用和类型本身视为同一个特征标,函数返回类型不同不能对函数进行重载
2.函数模板
(1)基本语法:
template<typename T>//typename可以用class替换 void Swap(T &a, T &b) { ... }
(2)重载的模板
template<typename T>//typename可以用class替换 void Swap(T &a, T &b) { ... } template<typename T>//typename可以用class替换 void Swap(T *a, T *b, int n) { ... }
(3)显示具体化---具体化函数定义
template<>void Swap<job>(job &, job &);//具体化的原型,也可以将<job>去掉 { ... }
template<>void Swap(job &, job &);//具体化的原型,也可以将<job>去掉
{
...
}
(4)实例化和具体化
1.直接调用模板函数为隐形实例化
2.显式实例化:template void Swap<int>(int &, int &);
(5)重载解析
对于函数重载、函数目标、函数模板重载,编译器选择使用哪个函数版本称为重载解析,将寻找最匹配的函数。
如果只存在这样一个函数,则选择它;
如果存在多个这样的函数,但其中只有一个时非模板函数则选择该函数
如果存在多个适合的函数,且它们都为模板函数,但其中有一个函数比其他函数更具体,则选择该函数
如果有多个同样合适的非模板函数或模板函数,但没有一个函数比其他函数更具体,则函数调用不确定,报错
如果不存在匹配的函数,报错
(6)C++11中两个关键字decltype和auto
decltype(expression) var
int x; decltype (x) y;//使y的类型与x相同
1、如果expression时一个没有用括号括起的标识符,则var的类型与该标识符的类型相同,包括const等限定符
int x;
double x1 = 5.5;
double &rx = x1;
const double * pd;
decltype (x) y;//y类型为int
decltype (rx) y = x1;//y类型是double &
decltype (pd) y;//y类型为const double *
2、如果expression是一个函数调用,则var的类型与函数的返回值类型相同,并不会实际调用函数。
long indeed(int); decltype (indeed(3)) y;//y类型为long
3、如果expression是一个左值,则var为指向该类型的引用
double xx; decltype ((xx)) y;//y类型为double &
decltype (xx) y = xx;//y类型为double
4、如果前面条件都不满足,则var的类型与expression的类型相同
int j = 3;
int &k = j;
int &n = j;
decltype (j + 6) y;//y类型为int
decltype (100L) y;//y类型为long
decltype (k+n) y = xx;//y类型为int 表达式k+n不是引用,是两个int的和,所以类型为int
(7)auto
double h(int x, int y);
等同于
auto h(int x, int y)->double;//后置返回类型
函数模板中类型问题可以用后置返回类型解决,decltype在参数声明后面,因此x和y位于作用域内,可以使用它们
template<class T1, class T2>
auto gt(T1 x, T2 y)->decltype(x+y)
{
...
}