c++ - 为什么这段代码有 C2784 "could not deduce template argument"错误

标签 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); });

编译错误:

error C2784: 'Range MyTest(Range,ValueType,bool (__cdecl *)(ValueType))' : could not deduce template argument for 'bool (__cdecl *)(ValueType)' from 'main::'

为什么会这样?我想通过传入 dValueType 可以推导为 double?

最佳答案

改用它(注意 +):

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); });
}

关于c++ - 为什么这段代码有 C2784 "could not deduce template argument"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40100778/

相关文章:

使用模板参数的 C++ 大括号初始化

linq - lambda 表达式中更深层次的 LINQ 查询

c++ - 检索用户路径环境变量

c++ - 查找动态分配数组的大小

php - PHP 中的超轻型模板系统,不允许模板内的 php 代码或使用 eval

c# - ActionBlock 可以包含状态吗?

javascript - 使用 hasOwnProperty 时无法将 null 或 undefined 转换为对象

c++ - 我可以创建一个 unique_ptr<T[]>(n), n 在运行时声明的数组,而不循环元素吗?

c++ - 一个简单的坦克 C++ 游戏

javascript - 如何使用JavaScript模板?