为什么这段代码有C2784“无法推断模板参数”错误

时间:2016-10-18 06:10:28

标签: c++ templates lambda function-pointers

Lambda function passed as parameter我可以编译示例:

template <class Range>
Range FindFirstIf(Range, bool(*Function)(typename Range::ConstReference value));

struct range {  using ConstReference = const float&; };

range rng;
rng = FindFirstIf(rng, [](const float& val) { return (val < 0.0f); });

当然无法链接,因为FindFirstIf未实现。

然而,当我做了类似的事情时:

template <class Range, class ValueType>
Range MyTest(Range, ValueType, bool(*Function)(ValueType value));

std::vector <int> vi;
double d = 0;
vi =       MyTest(vi, d, [](double val) { return (val < 0.0f); });

它有编译错误:

  

错误C2784:'范围MyTest(范围,ValueType,bool(__ cdecl   *)(ValueType))':无法推断'bool(__ cdecl *)(ValueType)'的模板参数   '主::'

为什么呢?我想通过传递dValueType可以推断为double

1 个答案:

答案 0 :(得分:2)

改为使用它(请注意+):

vi = MyTest(vi, d, +[](double val) { return (val < 0.0f); });

在某些情况下,Lambda函数可以衰减到函数指针,但它们不是函数指针。
换句话说,演绎失败是因为它期望在函数指针上工作,但lambda不是函数指针,当然可以转换它,但首先必须进行演绎,但它不能用于lambda而不是期望的类型,它可能会腐烂......依此类推。
通过在lambda前面添加+,可以在将转换传递给函数之前强制转换,因此MyTest会按预期接收实际的函数指针并继续扣除。

以下是基于代码的最小工作示例:

#include<vector>

template <class Range, class ValueType>
Range MyTest(Range, ValueType, bool(*Function)(ValueType value)) {}

int main() {
    std::vector <int> vi;
    double d = 0;
    vi = MyTest(vi, d, +[](double val) { return (val < 0.0f); });
}