4.2 非类型的函数模板参数
你也可以为函数模板定义非类型参数。例如,下面的函数模板定义了一组用于增加特定值的函数:
//basics/addval.hpp
template<typename T, int VAL>
T addValue(T const& x)
{
return x + VAL;
}
如果需要把函数或者操作用作参数的话,那么这类函数就是相当有用的。譬如,借助于标准模板库(STL),你可以传递这个函数模板的实例化体给集合中的每一个元素,让它们都增加一个整数值:
std::transform (source.begin(), source.end(), //源集合的起点
//和终点
dest.begin(), //目标集合的起点
addValue<int,5>); //操作(或者函数)
在上面的调用中,最后一个实参实例化了函数模板addValue(),它让int元素增加5。源集合source中的每一个元素都会调用实例化后的addValue()函数,并把调用结果放入目标集合dest。
另一方面,这个例子有一个问题:addValue<int,5>是一个函数模板实例,而函数模板实例通常被看成是用来命名一组重载函数的集合(即使该组只有一个函数)。然而,根据现今的标准,重载函数的集合并不能被用于模板参数的演绎。于是,你必须将这个函数模板的实参强制类型转换为具体的类型:
std::transform (source.begin(), source.end(), //源集合的起点
//和终点
dest.begin(), //目标集合的起点
(int(*)(int const&)) addValue<int,5>); //操作
现在有一个提议,建议C++(www.cppentry.com)标准解决这个问题,从而在这种情况下不需要进行强制类型转换(细节请见[CoreIssue115])。如果这个提议被通过的话,那么只有在考虑可移植性的情况下,才需要使用这种强制转型。