文章目录
7.1 非类型参数
- 非类型参数仅仅可以是整型、枚举、指针和引用。
- 模板代码不能修改非类型参数的值,也不能使用参数的地址。
- 实例化模板时,用作表达式参数的值必须是常量表达式。
实际上,建议使用构造函数而非类型参数。
7.2 递归使用模板
Array< Array<int, 5>, 10> twodee;
这使得teodee
成为一个包含十个元素的数组,每个元素都是一个包含五个int
元素的数组。
与之对应的常规数组声明如下:
int twodee[10][5];
7.3 模板的具体化
7.3.1 隐式实例化
编译器在需要对象前,都不会生成模板的显式具体化。
Array<double, 30> *pt; // 只是一个指针,不需要对象,没有生成显式具体化
pt = new Array<double, 30>; // 生成显式具体化
7.3.2 显式实例化
模板无法像函数一样用参数列表指出类型参数,所以<Type>
是必选的。另外,要注意加上class
关键字。
template class Array<string, 100>;
7.3.3 显示具体化
格式如下:
template <> class Classname<specialized-type-name>
{
// ...
}
某些编译器可能只能识别早期的格式,这种格式没有前缀template<>
:
class Classname<specialized-type-name>
{
// ...
}
7.3.4 部分具体化
假设已声明以下模板:
template <class T1, class T2>
class Pair
{
// ...
};
7.3.4.1 指定部分类型
template <class T2>
class Pair<int, T2>
{
// ...
};
部分具体化不会生成具体化的类,但是可以创建一个具体化程度更高的模板:
Pair<double, double> p1; // template <class T1, class T2> class Pair{...};
Pair<int, double> p2; // template <class T2> class Pair<int, T2>{...};
Pair<int, int> p2; // template <class T2> class Pair<int, T2>{...};
7.3.4.2 指出部分类型的更多细节
template <class T1*, class T2>
class Pair
{
// ...
};
Pair<double, string>; // template <class T1, class T2> class Pair{...};
Pair<char *, int>; // template <class T1*, class T2> class Pair{...};
7.3.5 模板别名(C++11)
template<typename T, int n>
class array
{
// ...
}
// ...
template<int n>
using arrint = array<int, n>;
// ...
arrint<50> nums; // array<int, 50> nums;
C++还允许将这种语法用于非模板:
using pint = int *;
using pcstr = const char*;