当参数包含 std::function 时,C++ 模板参数推导失败并出现错误 "candidate template ignored"... 为什么?
C++ template argument deduction is failing with error "candidate template ignored" when arguments include std::function... why?
我有以下功能:
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);
...并使用 bar
的模板参数推导
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)
^
这是为什么?从我的角度来看,很明显应该将参数类型推导为什么。
类型推导不考虑隐式转换,隐式转换稍后在重载解析期间发生。如果你直接传递 std::function ,它会正确推导。如果没有 std::function
的类型,它不能从你的 lambda 隐式构造一个 std::function
来知道它是否可能。我知道对我们来说,编译器似乎有足够的信息来正确推断所涉及的类型,但这是一个限制条件。
我有以下功能:
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);
...并使用 bar
的模板参数推导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)
^
这是为什么?从我的角度来看,很明显应该将参数类型推导为什么。
类型推导不考虑隐式转换,隐式转换稍后在重载解析期间发生。如果你直接传递 std::function ,它会正确推导。如果没有 std::function
的类型,它不能从你的 lambda 隐式构造一个 std::function
来知道它是否可能。我知道对我们来说,编译器似乎有足够的信息来正确推断所涉及的类型,但这是一个限制条件。