C++函数模板及其实例化和具体化

也许更好的阅读体验

函数模板

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)\)被称为后置返回类型

posted @ 2021-10-20 21:46  Morning_Glory  阅读(966)  评论(0编辑  收藏  举报
//