泛型
首先,在了解特化之前先了解一下什么是泛型:
泛型是程序设计语言的一种特性。允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明。
指的就是在程序设计时,添加一个模板这个模板可以是任意类型,而这个类型是在使用时给的。
template <class T>
struct A{...};
T 可以是任何数据类型,这是就是一个完全泛化的例子。
模板特化
C++中模板的实例化(instantiation)指函数模板(类模板)生成模板函数(模板类)的过程, 而模板特化(specialization)不同于实例化,模板参数在某种特定类型下的具体实现称为模板的特化。
而特化的意思则是对某些独特的类型作特殊的处理。由于一般性的模板定义对于某种类型来说并不适用,或是个别的的数据类型需要作个别处理。对泛型作一些特殊化,这就是模板特化
template<>
struct A<char>{
size_t getSize(char x) const {return x;}
};
template<>
struct A<int>{
size_t getSize(int x) const {return x;}
};
template<>
struct A<long>{
size_t getSize(long x) const {return x;}
};
当我们使用时指定的是char,int,long,则在此处会用这些个别的代码。
模板偏特化
偏特化(partial specialization)是模板特化的一种特殊形式,一般来说,所谓的特化是指将所有的模板参数进行替换成具体类型,而偏特化是指将部分参数类型指定为具体类型。
template<typename T,typename Alloc=...>
class vector{...};
绑定其中的一个值
template<typename Alloc=...>
class vector<bool,Alloc>{...};
这就是模板偏特化
模板模板参数
模板模板参数就是本身是一个模板的参数的模板,光说可能不太懂,下面的代码可以更助于理解:
template<typename T,template<typename T> class A>
class B{
public:
...
private:
A<T> a;
};
以上就是一个模板模板参数。模板模板参数允许使用者,传入一个容器并且传入容器的类型,让使用者使用时更具有弹性。
传入的第二参数自己是未定的模板,在classB中创建了一个以T为类型的A,A是我们传入的容器。
需要注意的是:容器可能会有第二模板参数,由于有默认值所以可能并没有被注意到,此时便会报错。
如何解决:
在使用前加入
template<typename T>
using Lst = list<T,allocator<T>>;
再使用B类
B<string,Lst> mylist;
当然如果是单一常数的模板可直接使用(除非有特殊情况)。
让我们看一个特殊情况,这是不是模板模板参数:
template<class T,class Sequence = deque<T>>
class stack{
...
protected:
Sequence c; //底层容器
...
};
stack<int> s1;
这并非模板模板参数,因为倘若我们这样使用:
stack<int,list<int>> s2;
那么第二参数将不是模板,而是一个确定的值,所以这并非模板模板参数。
总结:
- 泛型允许程序员在强类型程序设计语言中编写代码时定义一些可变部分。
- 模板的特化是模板参数在某种特定类型下的具体实现。
- 偏特化是指将部分参数类型指定为具体类型。
- 模板模板参数就是本身是一个模板的参数的模板。
如果有错误欢迎各位指出,谢谢!