【问题标题】:How to return a lambda function with a parameter?如何返回带参数的 lambda 函数?
【发布时间】:2015-02-16 03:04:16
【问题描述】:

我有一个函数模板,它接受一个可调用对象,包括如下所示的 lambda

template<class ValueT, class ValidatorF>
void myFun(ValueT& value, ValidatorF validate)
{
    ...
    if (validate(value)) ... // call to validate the value
    ...
}

我可以像下面这样使用它和一个验证器来测试一个整数是否大于 0

int i = 10;
myFun(i, [](int& value) {return value > 0;});

现在我想要一个验证器来测试一个整数是否大于特定数字(不仅仅是 0),我这样做了

auto greaterThan = [](int number) 
                   { return [number](int& value) { return value > number; }; };

但是上面的内容不能用 VS2013 编译。有什么错误或让它工作的方法吗?

我刚刚在 Coliru 进行了测试。没关系。也许那是由于VS2013。通过测试

int main()
{
    auto greaterThan = [](int number) 
                       { return [number](int& value) { return value > number; }; };
}

VS2013编译错误是

Error 1 error C2440: 'return' : cannot convert from 'main::&lt;lambda_20b9557a9ed9208edabcd15f35d83ad2&gt;::()::&lt;lambda_44761a42f06f1791bdbf89e7a9b3a961&gt;' to 'bool (__cdecl *)(int &amp;)' main.cpp 8

【问题讨论】:

  • 你需要一个分号。 return [number](int&amp; value) { return value &gt; number; } ;(除非你只是输入它,否则这可能不是你真正的问题。)
  • 你的编译错误是什么?也许 lambda 表达式需要一个返回类型:[] ( int number ) -> bool ...。据我所知,在某些版本的 MSVC 中需要显式定义返回类型。
  • 谢谢。这是一个错字。
  • @user1899020 正如您已经被问到的,请提供编译器错误。如果我们甚至不知道编译器为什么不高兴,我们就无法轻松地帮助您找出解决方法。
  • 对我来说编译正常,我试过了:int i = 5; auto f = greaterThan(10)(i);

标签: c++ c++11 visual-studio-2013 lambda


【解决方案1】:

除了 ecatmur 所说的,你可以决定实现你的 GreaterThan 方法的非curried版本,并使用std::bind 绑定第二个参数:

auto greaterThan = [](int num1, int num2) -> { return num1 > num2; };
myFun(i, std::bind(greaterThan, _1, number) );

【讨论】:

  • @user1899020 它应该是因为它不需要虚拟调用 lambda。此外,当在模板中使用 lambda 时,编译器可以一直看到它,因此它可能会将 lambda 直接内联到模板函数的实例化中。
【解决方案2】:

是的,这是 MSVC 的缺陷;它无法使用非空捕获列表处理对 lambda 的返回类型推导。

以效率低下为代价,您可以使用std::function 对 lambda 进行类型擦除:

#include <functional>

int main()
{
    auto greaterThan = [](int number) -> std::function<bool(int&)>
        { return [number](int& value) -> bool { return value > number; }; };
}

【讨论】:

    猜你喜欢
    • 2023-01-04
    • 2017-07-25
    • 2014-10-21
    • 1970-01-01
    • 2015-08-27
    • 1970-01-01
    • 2022-11-17
    • 2023-04-04
    • 1970-01-01
    相关资源
    最近更新 更多