17.1 函数模板
函数模板是一系列相关函数的模板或样板,这些函数的原代码形式相同,只是针对的数据类型不同。对于函数模板,数据类型本身成了它的参数,因而是一种参数化类型的函数。声明的格式是:
templete<<模板参数表>><函数声明>
其中的<模板参数表>由一个或多个<模板形参>组成,各<模板形参>之间用逗号隔开。每个<模板形参>具有下面几种形式:
template<参数名>
class<函数名>
<类型列表><参数名>
这里的<参数名>可以是任意的标识符。在这三种形式中,前两种是等价的:在声明模板参数时,关键字typename与class可以互换。用typename或class声明的参数称为虚拟类型参数;而用<类型修饰>声明的参数则称为常规参数,在形式上与普通的函数参数声明相同。
<函数声明>与一般函数的声明类似,只是某些类型修饰符被虚拟类型参数所替代。例:
template <class T>
void addTo(T a[],T b[],int size)
{
for(int i=0;i<size;i++) b[i]+=a[i];
}
其中用<>括起来的部分就是模板参数表,T是一个虚拟类型参数。
定义好函数模板后,编译系统将依据每一次对函数模板调用时实际所使用的数据生成适当的代码,并生成相应的函数版本。编译系统生成函数模板的某个具体函数版本的过程称为函数模板的实例化,每个实例就是一个函数定义。在实例化过程中,用实参的实际类型代替虚拟类型。
在调用一个函数模板时,编译系统需要足够的信息来辨别每个虚拟类型参数所对应的实际类型,可以从不同的渠道获得这样的信息:从模板实参表中的<>或模板实参表中的(),模板实参的信息优先于函数实参的信息。如果从后者获得的信息已经能够判定其中部分或全部虚拟类型参数所对应的实际参数,而且它们又正好是参数表中最后的若干参数,则模板实参表中的几个参数可以省略。因此,若x和y都是int型,则add<int>(x,y)、add<>(x,y)和add(x,y)等价。反之对于某个模板实参,如果模板函数的实参表中无法获得同样的信息,就不能省略;或者虽然能够获得同样的信息,但还有其他不能省略的实参,则不能省略。
参考《全国计算机等级考试二级教程——C++语言程序设计》