目录
模板全特化,偏特化
对特殊的类型(类型模板参数)进行特殊对待,给它写适合它的类型的专用代码。
类模板特化
类模板全特化
a)常规全特化
必须先有泛化版本,才有特化版本
特化版本编译器会优先选择
template<class T1 ,class T2>
struct TV{ //泛化TV类模板
TV(){
cout << "泛化版本构造函数" << endl;
}
void functest(){
cout << "泛化版本" << endl;
}
}
需求:当T1和T2都是int类型时,需要特殊处理。
全特化,就是所有的类型模板参数,都得用具体的参数进行代替从而实例化。
template<> //全特化,所用类型模板参数都用具体类型代替,所以template后面的模板参数列表为空
struct TV<int , int>{
//这里可以对该特化版本进行单独处理
TV(){
cout << "int,int特化版本构造函数" << endl;
}
void functest(){
cout << "int,int特化版本" << endl;
}
}
TV<char, int> ct_obj; //调用泛化版本构造函数
ct_obj.functest(); //调用泛化版本,实例化
TV<int, int> tt_obj; //调用特化版本构造函数
tt_obj.functest(); //调用特化版本
b)特化成员函数而不是模板
template<>
TV<char, char>::functest(){
cout << "char, chart的functest()特化版本函数" << endl;
}
TV<char, char> cc_obj; //调用泛化版本构造函数
cc_obj.functest(); //特化了char,char类型的functest函数,所以调用特化版本函数
类模板偏特化(局部特化)
a)模板参数数量
//泛化版本
template<class T, class U, class W>
struct TV{ //泛化TV类模板
void functest(){
cout << "泛化版本" << endl;
}
}
//从参数数量上偏特化,两个类型确定,一个不确定
template<class U> //其他两个绑定到具体类型,U不确定。
struct TV<int, U, double>{ //可以跳着进行特化
//这里可以对该特化版本进行单独处理
void functest(){
cout << "偏特化int, U, double特化版本" << endl;
}
}
TV<double, char ,double> dcd_obj; //调用泛化版本
TV<int, char ,double> icd_obj; //调用偏特化int, U, double版本
b)模板参数范围:int , const int(比int小)
原来类型为T,现在为T*, T比T范围小,从任意类型T,缩小到指针类型T 原来是T,现在为T&左值引用,或者T&&右值引用
template<class T>
struct TV{ //泛化TV类模板
void functest(){
cout << "泛化版本" << endl;
}
//范围上的特化版本
template<class T>
struct TV<const T>{ //const的特化版本
void functest(){
cout << "const的特化版本" << endl;
}
template<class T>
struct TV<T*>{ //T*的特化版本。告诉编译器,如果使用指针就调用这个版本
void functest(){
cout << "T*的特化版本" << endl;
}
template<class T>
struct TV<T&>{ //T&的特化版本
void functest(){
cout << "T&的特化版本" << endl;
}
template<class T>
struct TV<T&&>{ //T&&的特化版本
void functest(){
cout << "T&&的特化版本" << endl;
}
TV<double> tv_obj; //泛化版本
TV<double *> tv_obj; //T *特化版本
TV<const double *> tv_obj; //T *特化版本
TV<const double> tv_obj; //const T 特化版本
TV<int &> tv_obj; //T& 特化版本
TV<int &&> tv_obj; //T&& 特化版本
偏特化,特化完了本质上还是模板。
全特化,特化完了就是一个具体类了。
函数模板特化
//函数模板泛化版本
template<class T, class U>
void functest(T &val1; U& val2){
cout << "泛化版本" << endl;
cout << val1<< endl;
cout << val2 << endl;
}
const char* p = "I love JM";
int i = 1314;
functest(p, i); //T = const char* p,val1 = onst char* &, U = int, val2 = int &;
函数模板全特化
/
/全特化版本
template<>
void functest(int &val1; int& val2){
cout << "int ,int特化版本" << endl;
cout << val1<< endl;
cout << val2 << endl;
}
int m_a = 43;
double m_b=52.1
functest(m_a, m_b);
全特化函数模板等价于实例化一个函数模板,并不等价于函数重载。
//void functest(int &; int& ){}; 全特化等价于实例化一个函数模板重载函数
void functest(int &val1; int& val2)
{
cout << “重载函数” << endl;
};
functest(m_a, m_b); //调用重载函数,没调用全特化
编译器选择最合适的函数进行调用:普通优先(有普通就无需去实例化一个版本),特化版本,泛化版本。
函数模板偏特化
//函数模板不能偏特化
template<class U>
void functest<double, U>(double &val1; U& val2){
....... //非法使用显示模板参数
}
模板特化版本放置位置建议
模板定义,实现应放在一个.h文件中,
模板的特化版本,泛化版本应放在同一个.h文件中
.h文件中前面放泛化版本,后面放特化版本