1.定义与使用
代码:
#include <iostream>
using namespace std;
template <class Type> // class 为变量类型名,Type为变量,是个泛型标识符
class Stack {
private:
enum {MAX = 10};
Type items[MAX];
...
public:
Stock();
};
template <class Type>
Stack<Type>::Stack() {}; //模板类限定
int main()
{
Stack<int> kernels; // 会创建两个不同的栈,一个处理int类型,一个处理string类型。
Stack<string> colonels; // 必须显式地提供对象类型,不能像函数模版一样隐式提供。
}
2.非类型参数/表达式参数
代码:
#include <iostream>
using namespace std;
template <class T, int n> // int指出n的类型为int,此时不在用作泛型名,而是有了指定的类型。
// 这称为:非类型参数/表达式参数。
class ArrayTP {
private:
T ar[n];
public:
ArrayTP() {};
...
};
template <class T, int n>
ArrayTP<T, n>::ArrayTP() {}; //模板类限定
int main()
{
ArrayTP<double, 12> eggweights;
ArrayTP<double, 13> donuts; //每种数组大小都将生成自己的模板。
//也就是说,浙江生成两种独立的类模板。
}
分析:非类型参数/表达式参数有一些限制:只能是整型、枚举、指针或引用。
3.模板类使用多个类型参数
代码:
#include <iostream>
using namespace std;
template<class T1, class T2>
// 或,为类型参数提供默认值也是可以的
template<class T1, class T2 = int>
class Pair {
private:
T1 a;
T2 b;
};
template<class T1, class T2>
Pair<T1, T2>::Pair() {};
4. 类模板的具体化
具体化:分为隐式实例化、显式实例化和显式具体化。
①隐式实例化:
目前为止使用的都是隐式实例化,即:在声明对象的时候给出具体的类型。
例:
ArrayTP<int ,10> stuff;
②显式实例化:
使用关键字template,并指出具体类型来声明一个类。
例:
template class ArrayTP<string, 100>;
③显式具体化:
存在的意义:有时候,可能需要为特殊类型实例化时,对模板方法进行一些修改,做出不同的行为。
一般的,若一个通用类模板为:
template<typename T>
class SortedArray{
...
}
那么,我想提供一个专供char *类型使用的显式具体化SortedArray模板应使用:
template<> class SortedArray<char *>{
}
// template<>的尖括号可以这么理解:由于类型已经指明,因此尖括号内不再有泛型类型名。
此时,若声明变量:
SortedArray<int> scores; //使用通用类模板
SortedArray<char *> dates; //使用显式具体化类模板