指定模板函数参数的默认值

时间:2012-08-20 12:30:34

标签: c++ templates

你能解释为什么以下代码无法编译吗?一个明显的解决方法是添加Apply的1参数重载,是否有更简单的?

template <typename T>
T Identity(const T& i_val)
  {
  return i_val;
  }

template <typename Val, typename Fn>
Val Apply(const Val& v, Fn fn = Identity<Val>)
  {
  return fn(v);
  }

int main() {
  Apply(42);              // error: no matching function for call to 'Apply(int)'
  Apply(42, Identity<int>); // OK
  return 0;
}

3 个答案:

答案 0 :(得分:10)

模板参数推导不起作用 - 您无法从默认值中推断出参数的类型。但是,在C ++ 11中,您可以指定默认模板参数:

template <typename Val, typename Fn = Val(&)(Val const &)>
Val Apply(const Val& v, Fn fn = Identity<Val>)
{
   return fn(v);
}

答案 1 :(得分:6)

查找要调用的函数包括: 1.创建候选集,其中包括模板参数推导 2.确定最佳超载

如果我正确理解标准,只有实际的函数参数(即不是默认的参数)参与推导模板参数。因此,从参数42开始,编译器唯一可以推断的是Val = int。重载不会进入候选集,并且永远不会查看默认参数。

答案 2 :(得分:0)

Apply是一个模板化的函数。您需要执行Apply<MyValueType,MyFuncType>(42);

你可以合理地期望编译器将Val推断为int,但是你不能指望它推断出函数的类型,即使你已经给出了默认值参数。因此,它无法推断您是否正在尝试调用Apply函数的声明。