为什么数据成员不能在lambda捕获列表中呢

时间:2021-03-03 19:10:32

I have a class foo that has bar as a member variable.

我有一个类foo,它的成员变量是bar。

In another member function of the class, I'm writing a lambda function:

在这个类的另一个成员函数中,我写了一个lambda函数:

[bar](void){}

But I can't include bar in the capture list. Why is that?

但是我不能在捕获列表中包含bar。这是为什么呢?

2 个解决方案

#1


24  

You capture class members by saying this in the capture list. This has nothing to do with the fact that the member is const.

您通过在捕获列表中这样说来捕获类成员。这与该成员是成员这一事实无关。


Example:

例子:

#include <iostream>

struct Foo
{
    const int a = 0;
    int b;
    Foo() : b{42} {
        auto f = [this]() { std::cout << a << " " << b << std::endl; };
//                ^^^^ 
        f();
    }
};

int main() {
    Foo x;
}

#2


42  

Only objects with automatic storage duration can be captured by a lambda in C++11 (i.e. local variables and function parameters). If you want the effect of capturing a non-static class data member, you can either capture the this pointer as in Danvil's answer:

只有具有自动存储持续时间的对象才能在c++ 11(即局部变量和函数参数)中捕获。如果您希望捕获非静态类数据成员的效果,您可以捕获该指针,如Danvil的回答:

auto f = [this]{ std::cout << a << std::endl; };

or cache the data member's value in a local variable and capture that:

或者在局部变量中缓存数据成员的值,并捕获:

auto a = this->a;
auto f = [a]{ std::cout << a << std::endl; };

which will be much more concise in C++14:

在c++ 14中更简洁:

auto f = [a = this->a]{ std::cout << a << std::endl; };

The choice between these two options depends on whether you want to store the value a has right now or if you want to retrieve the value a has when the lambda is called. Note that in the case where this is captured you must ensure that the lifetime of the pointer object encloses the lifetime of the lambda a call to the lambda after the object is destroyed has undefined behavior. The more simple case that captures a copy of a is completely self-contained and has no such lifetime issues.

这两个选项之间的选择取决于您是要存储当前值a,还是要检索调用lambda时的值a。注意,在捕获该对象的情况下,您必须确保指针对象的生存期包含lambda的生存期,对象被销毁后对lambda的调用具有未定义的行为。捕获一个副本的更简单的例子是完全自包含的,并且没有这样的生存期问题。

#1


24  

You capture class members by saying this in the capture list. This has nothing to do with the fact that the member is const.

您通过在捕获列表中这样说来捕获类成员。这与该成员是成员这一事实无关。


Example:

例子:

#include <iostream>

struct Foo
{
    const int a = 0;
    int b;
    Foo() : b{42} {
        auto f = [this]() { std::cout << a << " " << b << std::endl; };
//                ^^^^ 
        f();
    }
};

int main() {
    Foo x;
}

#2


42  

Only objects with automatic storage duration can be captured by a lambda in C++11 (i.e. local variables and function parameters). If you want the effect of capturing a non-static class data member, you can either capture the this pointer as in Danvil's answer:

只有具有自动存储持续时间的对象才能在c++ 11(即局部变量和函数参数)中捕获。如果您希望捕获非静态类数据成员的效果,您可以捕获该指针,如Danvil的回答:

auto f = [this]{ std::cout << a << std::endl; };

or cache the data member's value in a local variable and capture that:

或者在局部变量中缓存数据成员的值,并捕获:

auto a = this->a;
auto f = [a]{ std::cout << a << std::endl; };

which will be much more concise in C++14:

在c++ 14中更简洁:

auto f = [a = this->a]{ std::cout << a << std::endl; };

The choice between these two options depends on whether you want to store the value a has right now or if you want to retrieve the value a has when the lambda is called. Note that in the case where this is captured you must ensure that the lifetime of the pointer object encloses the lifetime of the lambda a call to the lambda after the object is destroyed has undefined behavior. The more simple case that captures a copy of a is completely self-contained and has no such lifetime issues.

这两个选项之间的选择取决于您是要存储当前值a,还是要检索调用lambda时的值a。注意,在捕获该对象的情况下,您必须确保指针对象的生存期包含lambda的生存期,对象被销毁后对lambda的调用具有未定义的行为。捕获一个副本的更简单的例子是完全自包含的,并且没有这样的生存期问题。