函数模版特例化
例子:
//第一个版本;可以比较任意两个类型
template<typename T> int compare(const &T,const T&);
//第二个版本处理字符串字面常量;重载实现
template<size_t N,size_t M>
int compare(const char(&)[N],const char (&)[M]);
//第三个版本;模版特例化
template<> int compare(const char*const &p1,const char*const &p2);
当定义函数模版的特例化版本时,我们本质上接管了编译器的工作。即,我们为原模版的一个特殊实例提供了定义。重要的是要弄清:一个特例化版本本质上是一个实例,而非函数名的一个重载版本。
因此,如果我们使用了下面的调用:
compare("hi","tom");
使用两个函数模版都是可行的,且提供同样好的匹配。但是,接受字符数组参数的版本更特例化,因此编译器会选择它。
类模版偏特化
类模版部分特例化(partial specialization)
注意:我们只能部分特例化类模版,而不能部分特例化函数模版。
//原始的,最通用的版本
template<class T> struct remove_reference{
typedef T type;
};
//部分特例化版本,将用于左值引用和右值引用
template<class T> struct remove_reference<T&>//左值引用
template<class T> struct remove_reference<T&>//右值引用
由于部分特例化版本本质是一个模版,所以我们首先定义模版参数。类似任何其他特例化版本,部分特例化版本的名字和原模版名字相同,对每个未完全确定类型的模版参数,在特例化版本的模版参数列表中都有一项与之对应。在类名后,我们要为特例化的模版参数指定实参,这些实参列于模版名之后的尖括号中,这些实参与原始模版中的参数按位置对应。