我的人生可以有把玩单调的时间,但没有忍受厌倦的余地
——《海边的卡夫卡》
模板的特化
特化是在一个统一的模板不能在所有类型实例下正常工作时,需要定义类型参数在实例化为特定类型时函数模板的特定实现版本。
特化必须在同一命名空间下
进行,可以特化类模板也可以特化函数模板, 模板实例化时会优先匹配”模板参数”最相符的那个特化版本。
1. 类模板可以全特化和偏特化,类模板不支持重载
2. 函数模板只能全特化,函数模板支持重载
全特化的模板参数列表应当是空的,并且应当给出”模板实参”列表.
// 全特化函数模板
template<>
//const char* Max<const char*>(const char* left, const char* right)
const char* Max<>(const char* left, const char* right)//省略"模板实参"
{
return (strcmp(left, right) > 0) ? left : right;
}
// 全特化类模板
template <>
class SeqList <int>
{
public :
SeqList(int capacity);
~ SeqList();
private :
int _size ;
int _capacity ;
int* _data ;
};
注意类模板的全特化时在类名后给出了”模板实参”,但函数模板的函数名后没有给出”模板实参”。 这是因为编译器根据const char* Max<>(const char* left, const char* right)
的函数签名1.可以推导出来它是T Max(T left, T right)
的特化。
但是如果通过函数签名无法推导出特化版本的源模板,这是就需要写出”模板实参”.
//反例
template <class T>
void f(){ T d; }
template <>
void f(){ int d; }
此时编译器无法推导出f()
是由f<T>()特化来的
,编译时会有错误:
error C2912: 显式专用化;“void f<>(void)”不是函数模板的专用化
这时我们便需要显式指定”模板实参”:
template <class T>
void f(){ T d; }
template <>
void f<int>(){ int d; }