对于函数模板和类模板,模板参数并不局限于类型,普通值也可以作为模板参数。
1.非类型的类模板参数
1 |
|
为了使用上述模板,必须同时指定元素的类型和个数(即栈的最大元素容量)。
1 | Stack<int, 20> int20Stack; |
当然,上面的模板同样可以为模板参数设置缺省值:
1 | template <typename T = int, int MAXSIZE = 99> |
2.非类型的函数模板参数
你也可以为函数模板定义非类型参数。例如:
1 | template<typename T, int VAL> |
如果需要把函数或者操作用作参数的话,这类函数就相当有用。借助于标准模板库(STL),可以传递这个函数模板的实例化给集中的每一个元素,让他们都增加一个整数值:
1 | std::transform(source.begin(), source.end(), //源集合的起点和终点 |
上面的调用,最后一个实参实例化的函数模板addValue(),它上int元素加5。源集合source中的每一个元素都会加5将结果存在目标集合中。下面是一个使用std::transform()函数的例子:
1 |
|
运行结果:6 7 8
3.非类型模板参数的限制
非类型模板参数是有限制的,通常是常整数(包括枚举值)或者指向外部链接对象的指针。
浮点数和类对象是不允许作为非类型模板参数:
1 | template<double VAT> |
由于字符串文字是内部链接对象(因为两个具有相同名称但出于不同模块的字符串,是两个不同的对象),所以不能使用它们作为模板实参。
不能使用全局指针作为模板参数:
1 | template<char const* name> |
但是我们可以这样来使用:
1 | template<char const* name> |
全局字符数组s由”hello”初始化,是一个外部链接对象。
4.总结
- 模板参数不但可以是类型,也可以是值。
- 非类型模板参数,不能使用浮点数、class类的对象和内部链接对象(例如string)作为实参。
详情参考:《C++Templates》