定义类模板
- 模板类要以
template<typeame T>
代码开头
template
关键字告诉编译器要定义一个模板
T
不一定必须是类,只表示是一个通用类型说明符 - 模板函数
模板函数头都需要以相同的模板声明开头:
template<typename T>
bool Stack<T>::push(cost T&item)
{
...
}
如果在类声明内定义方法(内联),可以省略模板前缀和类限定符
不能把模板成员函数放在单独的实现文件中。
使用模板类
模板类的使用,必须实例化,使用需要的具体类型替换泛型名。
Stack<int> kernels;
Stack<string> colones;
深入探讨模板类
- 可以把用于常规类的技术用于模板类,模板类可用作基类,组件类,也可以用作其他模板的类型参数
template <typename T>
class Array
{
private:
T entry;
}
举例:模板类用作基类
template <typename T>
class GrowArray : public Array<T>
{
...
}
举例:模板类用作组件类
template <typename T>
class Stack
{
Array<T> ar;
}
举例;模板类用作其他模板类型参数
Array<Stack> asi;
- 递归调用模板
ArrayTP<ArrayTp<int, 5>, 10> twodee; - 使用多个类型参数
- 默认类型模板参数,为模板的类型参数提供默认值
template <class T1, class T2 = int> class Topo{...}
模板的具体化
具体化包含:隐式实例化,显示实例化,具体化
模板以泛型的方式描述类,具体化以具体的类型生成类声明
-
隐式实例化:直接声明对象,在声明对象的时候,直接指明类型;编译器在创建对象前,不会生成类的实例化
ArrayTP<int, 100> stuff;
-
显式实例化
template class ArrayTP<string, 100>
显式实例化,帮助我们隐藏模板的定义- 把模板声明放在头文件。
- 把模板定义放在源文件。在源文件的末尾进行显式模板实例化。
- 包含头文件来使用模板。
-
显式具体化
用于替换模板中的泛型定义
template <> class Classname<specialized type>{...}
成员模板
模板作为结构/类/模板类 的成员
template <typename T>
class beta
{
private:
template <typename V>
class hold;
hold<T> q;
hold<int> n;
public:
beta(T t, int i):q(t), n(i){}
template(U u, T t);
U blab(U u, T t);
}
//定义
template <typename T>
template <typename V>
class beta<T>::hold
{
......
}
template <typename T>
template <typename V>
U beta<T>::blab(U u, T t)
{
......
}
模板别名
- 用
typedef
为模板具体化指定别名
typedef std::array<int> arri;
arri days;
- 使用模板提供别名
template <typename T>
using arrtype = std::array<T, 12>;
arrtype<int> days;
- 延伸
C++11 允许用using
代替typedef
功能,增强可读性
typedef const char* pc1
using pc2 = const char *