C++全特化与偏特化
C++中用模板来实现代码的复用,模板分为类模板与函数模板,虽然模板引进到C++中的时间不长,可是却在很多方面有很多的应用,比如标准模板库STL中就有很多应用,然而当我们仔细的学习STL就会发现其中的模板充斥着很多的全特化与偏特化模板,那么什么是特化模板呢?
我们前面学习了模板知道了编译的时候编译器可以根据类型的不同实例化出不同的对象,可是如果有一个类型有更好的解决方案那么这个类型就可以不用这个模板,我们可以给这个类型设计一个新的解决方案,这种方式叫做特化。
特化分为全特化与偏特化,接下来我们先来看全特化
全特化
全特化就是对所有模板参数进行特化,当适配到相应的类型的时候直接按照特化版执行。
我们来看一个例子
#include<iostream>
#include<string>
#include<windows.h>
using namespace std;
template<class T>
class A
{
public:
A()
{
cout << "这里走的原始版本" << endl;
}
};
template<>
class A<int>
{
public:
A()
{
cout << "这里走的int特化版本" << endl;
}
};
int main()
{
A<char> a;
A<int> b;
system("pause");
return 0;
}
在上面这段代码中,第一个是对所有模板都适用的,第二个则是int的特化版本,那么当我们用其他类型进行实例化的时候会执行普通版本,当我们用int实例化的时候则会执行int特化版本
运行结果符合预期
偏特化
接下来让我们来看偏特化,首先还是先根据一个例子来看
#include<iostream>
#include<string>
#include<windows.h>
using namespace std;
template<class T1,class T2>
class A
{
public:
A()
{
cout << "这个是普通版本" << endl;
}
T1 _a;
T2 _b;
};
template<class T>
class A<T,int>
{
public:
A()
{
cout << "这个是偏特化版本" << endl;
}
T _a;
int _b;
};
int main()
{
A<double, double> a;
A<double, int> b;
system("pause");
return 0;
}
在这段代码中我们定义了一个适用于所有类型的版本,同时也定义了一个第二个类型是int的版本,我们来看看结果
结果可以看出,当我们第二个参数给成int的话他会自己去执行偏特化版本,这里我们可以总结出偏特化与全特化的一个区别,全特化中所有的模板类型都给定才可以执行全特化版本,但是偏特化我们可以只给定有限的模板类型即可。
那我们来看看下面这两种情况呢
template<class T1,class T2>
class A<t=T1&,t2&>
{
public:
A()
{
cout << "这是引用特化版本" << endl;
}
T1& _a;
T2& _b;
};
template<class T1,class T2>
class A<T1*,T2*>
{
A()
{
cout << "这个是指针特化版本" << endl;
}
T1* _a;
T2* _b;
};
这些其实都是偏特化,偏特化不是指对于部分类型进行限制,而是对参数模板更进一步的进行限制所形成的一个特化版本。
这里要注意一个事项:所有的特化都是在模板的基础上实现的。