如何立即调用 C++ lambda?

2021-12-23 00:00:00 lambda c++ c++11 c++14

来自我继承的类的构造函数需要传入一个非平凡的对象.类似于:

A constructor from a class I'm inheriting requires a non-trivial object to be passed in. Similar to this:

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

complexstuffMyFoo 关系不大,所以我不想传入.

The complexstuff has little to do with MyFoo, so I didn't want to have to pass it in.

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

Instead of writing some kind of 1-off temporary function that returns complexstuff I used a lambda. What took me a few minutes to figure out is I have to invoke the lambda. So my code now looks like this:

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

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

If you didn't catch it, it is subtle. But after the lambda body, I had to put () to tell the compiler to immediately "run" the lambda. Which made sense after I figured out what I had done wrong. Otherwise, without the () to invoke the lambda, gcc says something similar to this:

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

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

But now that has me thinking -- did I do this correctly? Is there a better way in C++11 or C++14 to tell the compiler that I want it to immediately invoke a lambda I've written? Or is appending an empty () like I did the usual way to do this?

推荐答案

但现在我在想――我做对了吗?

But now that has me thinking -- did I do this correctly?

是的,你做到了.

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

Is there a better way in C++11 or C++14 to tell the compiler that I want it to immediately invoke a lambda I've written?

我不知道.一个 lambda 也只是一个函数对象,所以你需要有一个 () 来调用它,没有办法绕过它(当然除了一些调用lambda 就像 std::invoke).

Not that I know of. A lambda is also just a function object, so you need to have a () to call it, there is no way around it (except of course some function that invokes the lambda like std::invoke).

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

If you want you can drop the () after the capture list, because your lambda doesn't take any parameters.

还是像我通常的做法那样附加一个空的 () ?

Or is appending an empty () like I did the usual way to do this?

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

Yes, it is the shortest way. As said before, std::invoke would also work instead, but it requires more typing. I would say a direct call with () is the usual way it is done.

相关文章