函数模板:需要创建针对不同参数类型的实现相同功能的不同函数。注:模板不能缩短可执行程序,最终仍是有多个独立的函数定义。
另,若对不同类型的参数执行不同的算法,可以重载模板定义,前提是两函数的特征标不同。
例:template <typename T> //或者class T
void Swap(T &a, T&b) //交换
{
T temp;
temp=a;
a=b;
b=temp;
}
显示具体化:当参数相同不能实现重载时,可以考虑显示具体化。原型和定义以template<>打头。具体化优先于常规模板,非模板函数优先于具体化和常规模板。
例:template <> void Swap<job>(job &j1, job &j2) //其中job是一种结构名
显示实例化:意思是“不要使用常规模板来生成函数定义,而应使用专门为Int类型显示定义的函数的定义”。以template开头。
例:template void Swap<int> (int a1, int a2)
类模板:调用时将具体的类型作为参数传递给这个类。例如经典的valarray(定义了数组中元素的数值操作)、vector、array。需要在类声明前、类函数定义前以template <class Type>开头,类限定符也要修改为classname<Type>::。
例:
template <class Type>
class Stack
{
private:
enum {MAX=10};
Type items[MAX];
int top;
public:
Stack();
……
}
template <class Type>
Stack<Type>::Stack()
{
top=0;
}
相比于函数模板,类模板必须显式的提供所需的类型。
类模板中非类型参数/表达式参数:可用于使用模板参数来提供数组的大小。
template <class T, int n> //其中n为表达式参数(指定特殊的类型)
例:声明对象:classname<double, 12> example; //使用double替换T,使用12替换n
注:1.表达式参数可以是整型、枚举、引用或指针。所以double等不合法;
2.模板代码不能修改参数的值,也不能使用参数的地址。例不能使用n++,&n等;
3.实例化模板时,用作表达式参数的值必须是常量表达式。