一 特化与偏特化
1.1 偏特化
综合STL 源码剖析中给出的两种定义,可以如下定义:所谓偏特化的意思是提供另一份更进一步条件的template定义式,其仍然是模板化的。举一个例子:
template<typename T>
struct Test{
typedef T value_type;
};
// 偏特化版本1
template<typename T>
struct Test<T*>{ // 可以把*看成是更进一步的条件,即该模板匹配的是指向T类型的指针(原始指针)
typedef T value_type;
};
// 偏特化版本2
template<typename T>
struct Test<const T*>{ // 可以把const和*看做更进一步的条件,即改模板匹配的是指向常量T的指针
typedef T value_type;
};
template<typename Tp>
void cout_type_name(Tp d){
cout << typeid(Tp).name()<<" " << typeid(Test<Tp>::value_type).name()<<endl;
}
int main()
{
int a = 3;
int *ptr = &a;
const int *cptr = &a;
cout_type_name(a); // 输出为:int int
cout_type_name(ptr); // 输出为: int* int
cout_type_name(cptr); // 输出为: int const * int
return 0;
}
其中的cout_type_name打印出的分别为Tp类型和使用偏特化萃取出的类型。当有多个模板参数时怎么写呢?举例如下:
typename<typename T1, typename T2>
struct Test{
...
}
typename<typename T1, typename T2>
struct Test<T1, T2*>{
...
}
template <typename T, typename U> struct is_same{ void printf(){std::cout<<"T,U"<<std::endl;} };
template <typename T> struct is_same<T,T> {void printf(){std::cout<<"T,T"<<std::endl;}}; // 偏特化
int main(int argc, char *argv[])
{
is_same<int, int> a;
a.printf(); // T T
is_same<int, char> b;
b.printf(); // T U
return 0;
}
1.2 特化
如果说偏特化是对某个模板增加进一步的限制条件,那么特化就是将模板的型别具体化到了某一种型别,可以说特化就是某种程度上的具体化。
函数模板的特化举例如下:
template<typename T1, typename T2>
void testFun(T1 a, T2 b) {
cout<< "T1, T2"<<endl;
}
template<typename T1>
void testFun(T1 a, int b) {
cout<< "T1, int"<<endl;
}
void testFun(int a, int b) {
cout<< "int, int"<<endl;
}
int main(){
testFun(true,true); // 输出:T1,T2
testFun(true,1); // 输出:T1,int
testFun(3,1); // 输出:int,int
return 0;
}
可以看到在第二个特化版本中将第二个模板参数型别具体化到了int,而第三个特化版本中将两个模板参数型别具体化到了int,int。至于类模板的写法如下:
template<typename T1, typename T2>
struct TwoType {
TwoType() {
cout << "T1,T2" << endl;
}
};
template<typename T1, typename T2>
struct TwoType<T1, T2 *> { //偏特化
TwoType() {
cout << "T1,T2*" << endl;
}
};
template<typename T1>
struct TwoType<T1,bool> { //特化,具体到了bool
TwoType() {
cout << "T1,bool" << endl;
}
};
template<>
struct TwoType<char, bool> { //特化,具体到了char,bool
TwoType() {
cout << "char,bool" << endl;
}
};