非类型模板参数
模板参数中不是只有类型的,非类型的模板参数,该参数类型是整形,浮点数等不可以。
#include<iostream> using namespace std; template<class T, int N>//N可以设置缺省值 class app { public: void print() { cout << a << endl; } private: T a = N; }; int main() { app<int, 10> a; a.print(); return 0; }
STL当中有一个array的容器:
第一个参数是类型,决定数组的类型,第二个是非类型,决定数组的容量。
这个容器可以对于数组下标是否越界进行检查,而C语言当中的数组是进行抽查。
模板的特化
举个例子,模板虽然能实例化各种类型,但是对于某些特殊类型进行实例化之后得不到想要的结果:
#include<iostream> using namespace std; template<class T> bool compare(T x, T y) { return x < y; } int main() { int a = 10; int b = 20; int c = compare(a, b);//这里比较的是a和b值的大小 cout << c << endl; int d = compare(&a, &b);//这里返回的结果就不一定是想要的了,因为比较的是地址 cout << d << endl; return 0; }
这时,就需要对模板进行特化。
即:在原模板类的基础上,针对特殊类型所进行特殊化的实现方式。
函数模板的特化
#include<iostream> using namespace std; template<class T> bool compare(T x, T y) { return x < y; } //特殊化 template<>//下面的<int*>省略这行也可以省略 bool compare<int*>(int* x, int* y)//这里也可以省略掉<int*> { return *x < *y; } int main() { int a = 10; int b = 20; int c = compare(a, b);//这里走模板 cout << c << endl; int d = compare(&a, &b);//这时候就不会走模板而是走模板的特化 cout << d << endl; return 0; }
类模板的特化
全特化
//原本的类模板 #include<iostream> using namespace std; template<class T1, class T2> class Date { public: Date() { cout << "正常模板" << endl; } private: T1 a; T2 b; }; //全特化 template<> class Date<int, char> { public: Date() { cout << "全特化" << endl; } private: int a; char b; }; int main() { Date<int, int>a1; Date<int, char>a2; return 0; }
偏特化
也称为半特化,只对部分参数进行特化,或者是更进一步的限制。
#include<iostream> using namespace std; template<class T1, class T2> class Date { public: Date() { cout << "正常模板" << endl; } private: T1 a; T2 b; }; //偏特化 template<class T> class Date<T, int> { public: Date() { cout << "偏特化" << endl; } private: T a; int b; }; int main() { Date<int, char>a1; Date<char, int>a2; return 0; }
进一步的限制
#include<iostream> using namespace std; template<class T1, class T2> class Date { public: Date() { cout << "正常模板" << endl; } private: T1 a; T2 b; }; //进一步限制 template<class T3,class T4> class Date<T3*, T4*>//也可以是引用版本 { public: Date() { cout << "进一步限制" << endl; } private: T3 a; T4 b; }; int main() { Date<int, char>a1; Date<int*, int*>a2; return 0; }
注意: 如果参数满足正常模板,偏特化,全特化,优先级的顺序是:
全特化>偏特化>正常模板