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

P45*_*ent 32 c++ lambda c++11

我有一个类foobar一个成员变量.

在该类的另一个成员函数中,我正在编写一个lambda函数:

[bar](void){}
Run Code Online (Sandbox Code Playgroud)

但我不能列入bar捕获列表.这是为什么?

Cas*_*sey 46

只有具有自动存储持续时间的对象才能被C++ 11中的lambda捕获(即局部变量和函数参数).如果你想要捕获non-static类数据成员的效果,你可以捕获this指针,如Danvil的答案:

auto f = [this]{ std::cout << a << std::endl; };
Run Code Online (Sandbox Code Playgroud)

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

auto a = this->a;
auto f = [a]{ std::cout << a << std::endl; };
Run Code Online (Sandbox Code Playgroud)

这将在C++ 14中更加简洁:

auto f = [a = this->a]{ std::cout << a << std::endl; };
Run Code Online (Sandbox Code Playgroud)

这两个选项之间的选择取决于您是否想要存储的价值a正确的现在,或者如果你想检索值a具有当拉姆达被调用.请注意,在this捕获的情况下,必须确保指针对象的生命周期包含lambda的生命周期,在销毁对象后调用lambda具有未定义的行为.捕获副本的更简单的情况a是完全独立的,并且没有这样的生命周期问题.

  • @Danvil正确.`[a = this-> a]`捕获`this-> a`的副本,但不需要像2行C++ 11版本那样在本地缓存`this-> a`的中间副本. (5认同)
  • 但是使用`[this]`与使用`[a = this-> a]`不一样 - 或者我错了? (2认同)
  • auto const&a = this-&gt; a; 保存一份? (2认同)
  • `auto f = [&a = this-&gt; a] {std :: cout &lt;&lt; a &lt;&lt; std :: endl; };`也可以通过引用捕获。 (2认同)

Dan*_*vil 24

您可以通过this在捕获列表中说明来捕获类成员.这与成员的事实无关const.


例:

#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;
}
Run Code Online (Sandbox Code Playgroud)

  • 这是不正确的.如果在捕获列表中指定`this`,则表示您正在捕获`this`指针的值,而不是类成员的值.你拥有的将在很多时候编译和工作,但你拥有的不是线程安全的.在创建lambda之后但在评估lambda之前,`a`和`b`的值可以改变.请参阅Casey的其他答案,以确保其安全. (5认同)
  • 您是正确的,但在最初的问题中,OP试图按值(而不是引用)捕获“ bar”。按值捕获“ this”指针将按引用捕获成员变量。 (2认同)