模板分为类模板和函数模板,特化分为全特化与偏特化。全特化就是限定死模板实现的具体类型,偏特化就是如果这个模板有多个类型,那么只限定其中的一部分。
模板为什么要特化,因为编译器认为,对于特定的类型,如果程序员能对某一功能更好的实现,那么就按照程序员的思路办。
全特化: 将模板参数列表中所有的参数都确切化
template <typename T>
class SeqList{
public:
SeqList();
~SeqList();
private:
int _size;
int _capacity;
T* _data;
};
template <typename T>
SeqList<T>::SeqList()
:_size(0)
,_capacity(10)
,_data(new T[_capacity]) {
std::cout << "SeqList<T>" << std::endl;
}
template <typename T>
SeqList<T>::~SeqList() {
delete []_data;
}
//全特化 int类型
template <>
class SeqList <int> {
public:
SeqList(int capacity);
~SeqList();
private:
int _size;
int _capacity;
int* _data;
};
//特化后定义成员函数不再需要模板形参
SeqList<int>::SeqList(int capacity)
:_size(0)
,_capacity(capacity)
,_data(new int[_capacity]){
std::cout << "SeqList<int>" << std::endl;
}
//特化后定义成员函数不再需要模板形参
SeqList<int>::~SeqList(){
delete []_data;
}
void test1(){
SeqList<float> sl2; //函数模板
SeqList<int> sl1(5); //全特化
}
偏特化: 任何针对模板形参进一步进行条件限制设计的特化版本
1)局部参数特化:
template <typename T1, typename T2>
class Data {
public:
Data(T1 d1,T2 d2);
private:
T1 _d1;
T2 _d2;
};
template <typename T1, typename T2>
Data<T1,T2>::Data(T1 d1,T2 d2)
:_d1(d1)
,_d2(d2){
std::cout << "Data<T1,T2>" << std::endl;
}
//局部特化第二个参数
template <typename T1>
class Data <T1,int> {
public:
Data(T1 d1,int d2);
private:
T1 _d1;
int _d2;
};
template <typename T1>
Data<T1,int>::Data(T1 d1,int d2)
:_d1(d1)
,_d2(d2) {
std::cout << "Data<T1,int>" << std::endl;
}
void test2(){
Data<float,int> d1(1.2,1); //局部参数特化
Data<int,int> d2(1,1); //局部参数特化
Data<float,float> d3(1.2,1.3); //非特化模板
}
在实例化类的时候,当在局部特化的位置上出现与之对应的类型,那么直接调用该局部特化版本。
2)局部特化两个参数为指针类型/引用
// 局部特化两个参数为指针类型
template <typename T1, typename T2>
class Data <T1*, T2*>
{
public :
Data();
private :
T1 _d1 ;
T2 _d2 ;
T1* _d3 ;
T2* _d4 ;
};
template <typename T1, typename T2>
Data<T1 *, T2*>:: Data()
{
cout<<"Data<T1*, T2*>" <<endl;
}
// 局部特化两个参数为引用
template <typename T1, typename T2>
class Data <T1&, T2&>
{
public :
Data(const T1& d1, const T2& d2);
private :
const T1 & _d1;
const T2 & _d2;
T1* _d3 ;
T2* _d4 ;
};
template <typename T1, typename T2>
Data<T1 &, T2&>:: Data(const T1& d1, const T2& d2)
: _d1(d1 )
, _d2(d2 )
{
cout<<"Data<T1&, T2&>" <<endl;
}
注:模板的全特化和偏特化都是在已经定义的模板基础之上的,不能单独存在。