《Absolute C++》 chapter 16
♦函数模板的函数定义和函数声明都是由如下代码开始的
template <class Type_Parameter>
♦之后便是函数的定义和函数体的定义,举例如下:
template<class T>
void swapValues(T& var1, T& var2)
{
T temp;
temp = var1;
var1 = var2;
var2 = temp;
}
♦例子中的T指代的是任意类型,包括系统自己定义的int,double,char等类型,也可以是自己写的类类型,并且,也可以声明不止用到一个类型,如:
template <class T1,class T2>
♦大部分情况下,我们都只用到一个定义,用到两个定义时需要相当小心,因为在函数模板的定义中,不能存在没有使用的模板参数(T1,T2)。也就是说,这里我们定义了T1,T2,不能只用到T1或者T2,必须两者都用到。(T1 temp1; T2 temp2这种就算使用了模板参数T1和T2)
♦函数也可以使用别的类型,但必须包含所定义的参数T, 例如
template<class T>
void showStuff(int stuff1, T stuff2, T stuff3)
♦ 这是完全合法的。
编译器在给程序中调用模板函数的每个不同的数据类型的时候,都生成了一个单独的函数定义,但是对于在程序中没有使用过数据类型,编译器则不会为他们生产实际的函数定义。而对于一个特定的数据类型而言 , 无论该类型的模板参数在程序中被调用了多少次,编译器只会为该类型生成一个函数定义。
♦ 在一些较复杂的函数中,如sort排序函数,需要函数嵌套,则在每个需要转换成模板函数的函数定义前,声明template语句,表明自己使用了哪些模板参数。 并且在编写较复杂的函数的时候,强烈建议先将具体某一类型的函数(即非模板函数) 实现其功能后,再用模板函数定义替换掉原先函数中的类型声明。直接使用模板函数定义容易出错,并且不利于Debug。
♦ 类模板的定义,同模板函数类似,都需要将
template <class T>
写在类定义之前。
♦成员函数的定义之前,也要将上述语句写在成员函数的定义之前。并且成员函数在作用域标识符::之前的类名是ClassName<T> ,而不是简单的ClassName, 但是在作用域标识符之后的构造函数的类名就变成了简单的ClassName,而没有<T>.
♦ 定义好了类模板,在声明该类的对象的时候,必须指定使用什么类型来代替类模板的中的类型参数T。
Pair<int> score;
Pair<char> seats;
为了详细的说明模板类的语法细节,以下为书上的总结: