1、模板特化按对象类型可分为类模板特化和全局模板函数函数特化;
2、按特化类型可分为全特化和偏特化(偏特化包括范围偏特化和参数数量偏特化),全局模板函数不支持偏特化(因为函数有重载,所以函数偏特化都是重载);
3、特化的优先级高于泛化(编译器会先去匹配特化和偏特化,后去匹配泛化)。
类模板特化
template <typename T1, typename T2>
class testFun
{
public:
testFun(T1 t1, T2 t2) : a(t1), b(t2)
{
cout << "类模板" << endl;
}
private:
T1 a;
T2 b;
};
//全特化
template <>
class testFun<int, string>
{
public:
testFun(int t1, string t2) : a(t1), b(t2)
{
cout << "全特化" << endl;
}
private:
int a;
string b;
};
//参数数量偏特化
template <typename T2>
class testFun<int, T2>
{
public:
testFun(int t1, T2 t2) : a(t1), b(t2)
{
cout << "参数数量偏特化" << endl;
}
private:
int a;
T2 b;
};
template <typename T1, typename T2>
class testFun<T1*, T2*>
{
public:
testFun(T1* t1, T2* t2) : a(t1), b(t2)
{
cout << "范围偏特化,指针偏特化" << endl;
}
private:
T1* a;
T2* b;
};
template <typename T1, typename T2>
class testFun<T1 const, T2 const>
{
public:
testFun(T1 t1, T2 t2) : a(t1), b(t2)
{
cout << "范围偏特化,const偏特化" << endl;
}
private:
T1 a;
T2 b;
};
函数模板特化
上面说到函数模板不支持偏特化,若强行写偏特化(重载),当同时写下特化和偏特化,若全特化的部分参数和偏特化的一致,则会给重载,退化为偏特化()
//函数模板
template<typename T1, typename T2>
void testfun(T1 ta, T2 t2) {
cout << "模板函数" << endl;
}
//全特化1,会被重载,退化为偏特化
template<>
void testfun(char ta, string t2) {
cout << "全特化" << endl;
}
//全特化2,不会被重载
template<>
void testfun(int ta, string t2) {
cout << "全特化" << endl;
}
//偏特化(重载)
template<typename T2>
void testfun(int t1, T2 t2) {
cout << "偏特化" << endl;
}
/*不支持const范围偏特化
template<typename T1, typename T2>
void testfun(T1 const t1, T2 const t2) {
cout << "const偏特化" << endl;
}*/
template<typename T1, typename T2>
void testfun(T1* t1, T2* t2) {
cout << "指针偏特化" << endl;
}