- 非类型模板参数
- 模板的特化
- 函数模板的特化
- 类模板的特化
- 全特化
- 偏特化
- 偏特化的两种形式
- 1.部分特化
- 2.进一步限制
前几篇的文章介绍了模板的使用基础,本篇文章主要介绍一下c++中模板的特化。
非类型模板参数
先额外介绍个知识点,非类型模板参数。
模板参数可以是一个类型,也可以是一个常量,如果是常量,那么这个模板参数就叫做非类型模板参数。
例如STL中的array的实现:
templateclass A { public: typedef size_t iterator; typedef const size_t const_iterator; array() { size = N; } T& operator[](const T& idx) { assert(idx < size); return _a[idx]; } iterator begin() { return 0; } iterator end() { return size - 1; } private: T arr[N];//固定大小的数组 size_t size; }
array使用格式:array<类型,数组大小> 对象名; arrayarr;
array 的成员变量中有一个长度固定的数组arr,array 的模板参数中第二个参数就是N就是非类型模板参数,为常量,在类中可以将该非类型模板参数当成常量来使用;但是也有限制,一般都是整型,浮点型、类、对象、字符串等都是不可以用来做非类型模板参数的。(非类型模板参数必须在编译的时候就能确定)
模板的特化- 虽然模板可以实现一些与类型无关的代码,但是有时候会有冲突,得到的结果不是我们想要的
例如:
//比较函数 templatebool greater( T left,T right) { return left > right; } void test() { Date d1(2002,2,1); Date d2(2003,4,9); cout< 这个时候模板的特化就派上了用场,就是在原来的模板类基础之上,针对特殊类型所进行特殊化的实现方式。
函数模板的特化函数模板特化的规则:
1.必须要有一个基础的函数模板作为前提
2.关键字template后接一个空的<>
3.函数名后跟一对<>,在其中指定需要特化的类型
4.函数形参列表必须要和模板函数参数类型完全相同,如果不同编译器会报错。
//函数模板的特化 templatebool greater( T left,T right) { return left > right; } template<> bool greater ( Date* left, Date* right) { return *left > *right; } //一般的函数模板可以不特化 直接给出 类模板一般才特化 bool greater(Date* left, Date* right) { return *left > *right; } //此时调用下面的函数的时候就会走特化后的比较函数了,得到的就是正确的结果了 void test() { Date d1(2002,2,1); Date d2(2003,4,9); cout< 类模板的特化 全特化
- 全特化就是将模板参数列表中所有的参数都确定化
规则与函数模板基本相同。
template偏特化class A { public: A() { cout << "A " << endl; } }; //全特化 template<> class A { public: A() { cout << "A " << endl; } }; 偏特化的两种形式 1.部分特化
- 偏特化就是对模板参数进行进一步的条件限制。
//以下面的模板为基础模板 templateclass Action { public: Action() { cout<<"Action"< class Action { public: Action() { cout<<"Action"< class Action { public: Action() { cout<<"Action "< 2.进一步限制
- 偏特化不仅仅时指特化部分参数,而是针对模板参数更进一步的条件限制所设计出来的一个特化版本。
templateclass A { public: A() { cout << "A " << endl; } } //进一步限制 限制两个参数为都必须为指针类型 template class A { public: A() { cout << "A " << endl; } }; //进一步限制第一个参数是指针类型,第二个参数是引用类型 template class A { public: A() { cout << "A " << endl; } };



