2016-07-29 96 views
1

我有以下功能:当参数包括std :: function ...时,C++模板参数演绎失败,错误为“候选模板被忽略”...为什么?

template <class InType, class OutType> 
OutType foo(const InType &a, std::function<OutType (const InType &)> func) 
{ 
    return func(a); 
} 

template <class T> 
T bar(T a, T b) 
{ 
    return a + b; 
} 

我可以给他们打电话,像这样:

double x = foo<int, double>(1, [] (const int &v) { return float(v) * 1.5f; }); 
double y = bar<int>(1.0, 2.0); 

...,并与酒吧

double z = bar(1.0, 2.0); 

使用模板实参推演......但如果我尝试使用foo使用模板参数演绎:

double w = foo(1, [] (const int &v) { return float(v) * 1.5f; }); 

它失败,此错误:

no matching function for call to 'foo' 
    double w = foo(1, [] (const int &v) { return float(v) * 1.5f; }); 
       ^~~ 
note: candidate template ignored: could not match 'function<type-parameter-0-1 (const type-parameter-0-0 &)>' against '(lambda at ../path/to/file.cpp:x:y)' 
OutType foo(const InType &a, std::function<OutType (const InType &)> func) 
     ^

这是为什么?从我的观点来看,很明显什么样的参数类型应该被推断为。

回答

2

类型扣减不考虑隐式转换,这在稍后的重载解析期间会发生。如果你直接传递一个std ::函数,它会正确推导出来。它不能隐式地从你的lambda构建一个std::function而不知道std::function是否可能。我知道,看起来编译器有足够的信息来正确推断所涉及的类型,但这是一个限制。

+0

类型扣除仅考虑* some *隐式转换。不涉及转换构造函数。 – Brian

+0

这种情况太糟糕了。否则就可以表达一些权力逻辑,而不需要C++的典型冗长和模板模糊。 – GuyGizmo