一. 为什么需要特化
特殊类型需要特殊处理
比如,实现了一个小于的仿函数,当想要比较的T是Date类时,想要按照特定的比较方式来比较,又想在形式上和其他类型一样,就需要特化
template <class T>
struct Less
{
bool operator()(T x,T y)
{
return x < y;
}
};
二.函数模板特化
步骤
- 先有一个基础的函数模板
- template后加 <>
- 函数名后加 <类型名>
- 形参列表必须要和函数模板相对应
template <class T>
bool Less(T x,T y)
{
return x < y;
}
//对Less函数进行特化
template<>
bool Less<Date*>(Date* x,Date* y)
{
return *x < *y;
}
三.类模板特化
全特化
将模板参数列表中的参数全都确定化
步骤
和函数模板特化一样
template<class T1, class T2>
class Data
{
public:
Data()
{cout<<"Data<T1, T2>" <<endl;}
private:
T1 _d1;
T2 _d2;
};
//对Date进行全特化
template<>
class Data<int, char>
{
public:
Data()
{cout<<"Data<int, char>" <<endl;}
private:
int _d1;
char _d2;
};
偏特化
【 注意 】
只有类模板有偏特化,函数模板没有,但是函数重载可以达到偏特化的效果
部分特化
可以部分特化任意一个参数,和缺省参数不同
步骤
template后要加上没被特化的参数
// 将第二个参数特化为int
template <class T1>
class Data<T1, int>
{
public:
Data()
{cout<<"Data<T1, int>" <<endl;}
private:
T1 _d1;
int _d2;
};
参数限制
对模板参数进行条件限制
比如,把参数特化成指针类型,所有指针的实参都会走这条路径
步骤
template后要加上要特化的参数,具体看代码
//两个参数偏特化为指针类型
template <typename T1, typename T2>
class Data <T1*, T2*>
{
public:
Data()
{cout<<"Data<T1*, T2*>" <<endl;}
private:
T1 _d1;
T2 _d2;
};