函数模板
C++函数模板实质上是一个生成函数的方式,它的目的是减少重复劳动。在调用函数模板时,编译器会生成一个函数实例,这种方式被称为隐式实例化。当我们对不同类型的变量执行同样的操作时,如果用函数重载,会麻烦很多。
例如,我们打一个绝对值函数
int fabs (int a)
{
return a>0?a:-a;
}
如果我们要对double类型也用绝对值函数,我们又得再打一个
double fabs (double a)
{
return a>0?a:-a;
}
但如果用函数模板,那么就只用打一次,不仅int,double都可以用,long ,float甚至自定义的类型也可以用。
template <class T>
T fabs (T a)
{
return a>0?a:-a;
}
//定义两个不同类型的模板这样使用
template <class T1,class T2>
函数显式实例化
即指示编译器直接创建一个函数实例,上面说到,函数模板是一个生成函数的方式,显式实例化就是告诉编译器生成一个函数。
用法
template 函数类型 函数名 <模板类型>(模板类型);//尖括号可省略
eg:
template int fabs <int> (int a);
template int fabs (int a);
上述两种写法是一样的
强制实例化
调用函数时可告诉编译器使用哪种类型进行实例化,类似于变量的强制转化。
用法举例
fabs<long long>(a)
函数显式具体化
当我们对不同类型要做不同处理方式时就用具体化。编译器会对具体化的类型专门使用这个函数,类似于函数重载,不过这是对函数模板的特例化处理。
用法
template <> 函数类型 函数名 <模板类型>(模板类型)//尖括号可省略
{
函数内容
}
eg:
template <> float fabs <float> (float a)
{
return a+1;//随便写的内容
}
当我们调用函数时传入的参数是两个float时会使用上述函数
注意不能对实例化和具体化一样类型的函数模板,但可以另外定义相同类型相同名字的函数,即下面的代码不能同时存在
template <> int fabs (int a)
{
return a+1;
}
template int fabs (int a);
但下面的代码可以
template int fabs (int a);//或者具体化
int fabs (int a)
{
return a+2;//随便写的
}
调用函数时,在变量类型匹配的上时,优先使用非模板类型的,也可这样操作告诉编译器使用模板类型的函数
fabs<>(a);
关键字(decltype)
当我们使用了复数个模板时,如
template <class T1,class T2>
T1 f (T1 a,T1 b);
如果我们新定义一个变量(c,c=a+b)
那么(c)的类型是什么呢,举个例子
f(1,5.5)//①
f(5.5,1)//②
如果c是T1类型,那么①中本应该是6.5变成了6,如果是T2类型,那么②中则变成了6
而关键字(decltype)就能很好的解决这种问题
我们这么声明c变量,
decltype(a+b) c=a+b;
这表示定义一个类型和a+b一样的变量
后置返回类型
只有(decltype)是不够用的,这无法满足对函数返回值的定义
于是有了这么个语法
auto f (T1 a,T1 b) -> decltype (a+b)
这将返回值类型的声明后置了,(->decltype(a+b))被称为后置返回类型