【问题标题】:Lambda function passed as parameter作为参数传递的 Lambda 函数
【发布时间】:2014-09-11 18:07:26
【问题描述】:

我有以下功能:

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

对于这个函数,我试图传递一个像这样的 lambda 函数:

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

其中rng 是浮点列表的范围,因此Range::ConstReference 定义为const float&amp;

我的编译器 (gcc) 抱怨类型不匹配

C:\Programming\Collections\main.cpp|24|note:   mismatched types 'bool (*)(typename Range::ConstReference)' and 'main(int, char**)::< lambda(const float&) >'|

谁能告诉我我的代码有什么问题?

编辑:

当我像这样传递函数时,它可以工作:

bool (*func)(const float&amp; v) = [](const float&amp; v) { return v &lt; 0.0f; };

当我尝试使用 auto 关键字时,问题和以前一样:

auto func = [](const float& v) { return v < 0.0f; };

【问题讨论】:

  • 你应该检查val,而不是v
  • 您已经有了解释问题所在的答案,但也可能有用的是一种解决方法:rng = FindFirstIf(rng, +[](const float&amp; v) { return (v &lt; 0.0f); });+ 强制将 lambda 直接转换为函数指针(因为 lambda 类不提供重载的 + 运算符,但确实提供了一个转换为指针的运算符,其结果可以是 +已应用),而 GCC 4.8 不会将其检测为不匹配的类型。
  • @hwd 谢谢这是非常好的解决方法
  • @manlio 我不确定您为什么觉得有必要在此处编辑标签,但如果您要这样做,请确保使用正确的标签。 OP 没有使用 GCC 4.9。我们可以从代码不适用于 OP 的事实中知道这一点。
  • @hvd 从接受的答案看来,它似乎是 v4.9 中解决的 gcc 错误

标签: c++ c++11 lambda


【解决方案1】:

我怀疑您的代码中有一个 type-o,或者您使用的 gcc 版本没有完全实现 lambdas(或可能两者兼有)。

如果你的例子是:

[](const float& val) { return (val < 0.0f); }

(v -> val)

并且如果Range::ConstReferenceconst float&amp;,那么代码是合法的C++11。

这里的棘手部分是 一些 lambdas 将隐式转换为函数指针。也就是说,那些没有 lambda-capture 的 lambda 将转换为具有相同签名的函数指针。

这个:

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

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

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

为我编译。

稍微研究一下在线 gcc 编译器,这似乎是 gcc 4.8 中的一个错误,已在 4.9 中修复。

【讨论】:

  • 谢谢。 val - v 只是一个错字,所以看起来问题出在我的编译器版本中。
最近更新 更多