模板的全特化与偏特化

模板的全特化与偏特化

模板函数和模板类有的时候可能需要对传入的不同类型进行不同的处理,比如说有的模板传入int或double类型都可以处理,但是传入char型则会出错,这时就需要模板特化的方式。

类模板全特化:

全特化即将模板类型里的所有类型参数全部具体指明之后处理,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template<typename T,typename C>
struct A
{
A(){cout<<"泛化版本构造函数"<<endl;}
void func()
{
cout<<"泛化版本"<<endl;
}
};

template<>//把类型取出
struct A<int,int>
{
A(){cout<<"int,int特化版本构造函数"<<endl;}
void func()
{
cout<<"int,int特化版本"<<endl;
}
};

template<>中为空,代表所有类型都在下面特殊化处理,上面相当于对int,int进行了分别的处理,其他类型依然是泛化版本。

对类中的某个成员函数进行特化处理

还是以上面给的例子为基础,特化func()成员函数,当A的模板参数为<int,double>时,调用特化版的func()。

1
2
3
4
5
template<>
void A<int,double>::func
{
cout<<"int,double特化版本函数"<<endl;
}

类模板的偏特化

类模板偏特化(局部特化):顾名思义,只特殊化几个参数或者一定的参数范围

个数偏特化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template<typename T,typename C,typename D>
struct A
{
void func()
{
cout << "泛化版本" << endl;
}
};

template<typename C>
struct A<int,C,int>
{
void func()
{
cout << "int,C,int偏特化版本" << endl;
}
};

template<>括号中存留的参数是依然可以任意填的参数。

STL中的一个个数偏特化例子:

1
2
3
//泛化
template <class T,class Alloc = alloc>
class vector{}
1
2
3
4
//特化
template <class Alloc>
class vector<bool, Alloc>
{};

范围偏特化

记住这种情况的template<>中还是要填上原有的大类型,且const T*属于T*不属于const T

注意范围二字,比如const int属于int的一个小范围,int *和const int*属于int的一个小范围,int&属于int的一个小范围,int&&属于int的一个小范围

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
template<typename T>
struct A
{
void func()
{
cout << "泛化版本" << endl;
}
};

template<typename T>
struct A<const T>
{
void func()
{
cout << "const T版本" << endl;
}
};

template<typename T>
struct A<T*>
{
void func()
{
cout << "T*版本" << endl;
}
};

STL中的一个范围偏特化例子:
在这里插入图片描述