如何立即调用 C lambda?

新手上路,请多包涵

我正在继承的类的构造函数需要传入一个重要的对象。与此类似:

 MyFoo::MyFoo() : SomeBase( complexstuff )
{
    return;
}

complexstuffMyFoo 没什么关系,所以我不想把它传入。

我没有编写某种返回 complexstuff 的 1-off 临时函数,而是使用了 lambda。我花了几分钟才弄清楚我必须 调用 lambda。所以我的代码现在看起来像这样:

 MyFoo::MyFoo() : SomeBase(
    []()
    {
        /* blah blah do stuff with complexstuff */
        return complexstuff;
    } () )
{
    return;
}

如果你没有抓住它,它是微妙的。但是在 lambda 主体之后,我不得不放 () 告诉编译器立即“运行” lambda。在我弄清楚我做错了什么之后,这是有道理的。否则,如果没有 () 来调用 lambda,gcc 会这样说:

 error: no matching function for call to 'SomeBase(<lambda()>)'

但现在这让我想到——我做对了吗?在 C++11 或 C++14 中是否有更好的方法来告诉编译器我希望它立即调用我编写的 lambda?或者是附加一个空的 () 就像我用通常的方法做的那样?

原文由 Stéphane 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 952
2 个回答

但现在这让我想到——我做对了吗?

是的,你做到了。

在 C++11 或 C++14 中是否有更好的方法来告诉编译器我希望它立即调用我编写的 lambda?

从来没听说过。 lambda 也只是一个函数对象,所以你 需要 一个 () 来调用它,没有办法绕过它(当然除了一些调用 lambda 的函数,比如 std::invoke )。

如果您愿意,可以在捕获列表之后删除 () ,因为您的 lambda 不采用任何参数。

或者是附加一个空的 () 就像我用通常的方法做的那样?

是的,这是最短的方法。如前所述, std::invoke 也可以代替,但它需要更多的输入。我想说直接调用 () 是通常的方式。

原文由 Rakete1111 发布,翻译遵循 CC BY-SA 3.0 许可协议

没有办法告诉编译器立即调用 lambda。最简单的课程(就复杂性和键入字符的数量而言)是您已经完成的。对于任何使用过闭包语言的人来说,这也是非常惯用的(我在这里考虑的是 JavaScript)。

如果要避免使用该语法,请修改 SomeBasecomplexstuff 以执行可调用文件。


如果你想要的只是调用 lambda 的语法糖,你总是可以做 Alexandrescu 的 SCOPE_GUARD 所做的事情,并滥用运算符重载:

活生生的例子

#include <iostream>

namespace detail {

enum class invoke_t{};

template<class Callable>
auto operator+(invoke_t, Callable c) -> decltype(c()) {
    return c();
}

}

constexpr detail::invoke_t invoke{};

int main() {
    invoke + []() {
        std::cout << "called";
    };
}

但我不会。发明你自己的 DSL 只会让你的代码更难维护。坚持使用简单语言结构的习语。

原文由 StoryTeller - Unslander Monica 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题