当参数包含std :: function时,C ++模板参数推导失败,错误“候选模板被忽略”...为什么?

时间:2016-07-29 22:13:06

标签: c++ templates argument-deduction

我有以下功能:

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)
        ^

为什么?从我的观点来看,很明显应该推断出论证类型是什么。

1 个答案:

答案 0 :(得分:2)

类型推导不考虑隐式转换,后者在重载解析期间发生。如果你直接传递一个std :: function,它会正确地推断出来。它不能隐含地从你的lambda构造一个std::function而没有std::function的类型来知道它是否可能。我告诉我们,看起来有足够的信息让编译器正确推导出所涉及的类型,但这是一个约束。