(1) 类模板的偏特化
例如c++标准库中的类vector的定义
template <class T, class Allocator>
class vector { // … // };
template <class Allocator>
class vector<bool, Allocator> { //…//};
这个偏特化的例子中,一个参数被绑定到bool类型,而另一个参数仍未绑定需要由用户指定。
(2) 函数模板的偏特化
严格的来说,函数模板并不支持偏特化,但由于可以对函数进行重载,所以可以达到类似于类模板偏特化的效果。
template <class T> void f(T); (a)
根据重载规则,对(a)进行重载
template < class T> void f(T*); (b)
如果将(a)称为基模板,那么(b)称为对基模板(a)的重载,而非对(a)的偏特化。C++的标准委员会仍在对下一个版本中是否允许函数模板的偏特化进行讨论。
/* 此处内容有待考证*/
模板函数可以有进行如下的偏特化定义:
template<> functionname<int>(int &t1 , int &t2){...} 或者
template functionname<int>(int &t1 , int &t2){...} 或者
template functionname(int &t1 , int &t2){...}
这三种定义是等同的.
这些声明的意思是:不要使用functionname函数模板来生成一个函数定义,而应该使用独立的、专门的函数定义显示的为数据类型int生成函数定义.
当编译器找到与函数调用匹配的偏特化定义的时候,编译器会优先使用该定义,而不再寻找模板定义。
(5)模板特化时的匹配规则
(1) 类模板的匹配规则
最优化的优于次特化的,即模板参数最精确匹配的具有最高的优先权
例子:
template <class T> class vector{//…//}; // (a) 普通型
template <class T> class vector<T*>{//…//}; // (b) 对指针类型特化
template <> class vector <void*>{//…//}; // (c) 对void*进行特化
每个类型都可以用作普通型(a)的参数,但只有指针类型才能用作(b)的参数,而只有void*才能作为(c)的参数
(2) 函数模板的匹配规则
非模板函数具有最高的优先权。如果不存在匹配的非模板函数的话,那么最匹配的和最特化的函数具有高优先权
例子:
template <class T> void f(T); // (d)
template <class T> void f(int, T, double); // (e)
template <class T> void f(T*); // (f)
template <> void f<int> (int) ; // (g)
void f(double); // (h)
bool b;
int i;
double d;
f(b); // 以 T = bool 调用 (d)
f(i,42,d) // 以 T = int 调用(e)
f(&i) ; // 以 T = int* 调用(f)
f(d); // 调用(h)