C++11/14之模板全特化,偏特化

目录

  • 模板全特化,偏特化
    • 类模板特化
      • 类模板全特化
        • a)常规全特化
        • b)特化成员函数而不是模板
      • 类模板偏特化(局部特化)
        • a)模板参数数量
        • b)模板参数范围:int , const int(比int小)
    • 函数模板特化
      • 函数模板全特化
      • 函数模板偏特化
    • 模板特化版本放置位置建议

模板全特化,偏特化

对特殊的类型(类型模板参数)进行特殊对待,给它写适合它的类型的专用代码。

类模板特化

类模板全特化

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文件中前面放泛化版本,后面放特化版本

你可能感兴趣的:(C++11/14/17)