你能解释为什么下面的代码不能编译吗?一个明显的解决方法是添加1参数重载 Apply
,有更简单的吗?
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;
}
查找要调用的函数包括:
1.创建候选集,其中包括模板参数推导
2.确定最佳过载
如果我正确理解标准,只有实际的函数参数(即不是默认的参数)参与推导模板参数。因此从论证 42
,编译器唯一可以推断的是 Val
= int
。重载不会进入候选集,并且永远不会查看默认参数。
模板参数推导不起作用 - 您无法从默认值推导出参数的类型。但是,在C ++ 11中,您可以指定默认模板参数:
template <typename Val, typename Fn = Val(&)(Val const &)>
Val Apply(const Val& v, Fn fn = Identity<Val>)
{
return fn(v);
}
Apply是一个模板化的函数。你需要这样做 Apply<MyValueType,MyFuncType>(42);
您可以合理地期望编译器推断 Val
成为 int
,但你不能指望它推断出函数的类型,即使你已经给出了一个默认参数。因此,它不会推断您正在尝试调用该声明 Apply
功能。