按价值类成员捕获

Lor*_*one 26 c++ lambda closures c++11

在成员函数中编写lambda函数时,有没有办法按值捕获封闭类的字段?默认的catch-all =不起作用,因为当我在lambda中引用变量时,我得到的是从捕获的this指针中取消引用,以及在捕获列表中显式命名变量,因为我得到两个编译错误:capture of non-variable <name>,和‘this’ was not captured for this lambda function

Jam*_*lis 30

不,数据成员无法按值捕获.lambda只能捕获两种东西:

  1. this指针,
  2. 非静态局部变量(即具有自动存储持续时间的变量).

正如注释中的ildjarn所指出的,您可以创建一个带有数据成员值副本的局部变量,并按值捕获该局部变量.

我认为,如果允许对数据成员进行显式的按值捕获,则可能会造成混淆,因为显式捕获的行为与隐式捕获的行为不同.例如,给定一个类型int为named 的可访问数据成员,m以下将产生不同结果将是奇怪的:

[=] () mutable { m = 1; } // we modify this->m
[=m]() mutable { m = 1; } // we modify the copy of m that was captured
Run Code Online (Sandbox Code Playgroud)

  • @MooingDuck:lambda捕获总是从本地范围捕获变量.成员变量不在语言环境范围内,因此您无法触及它们.此外,该成员实际上是作为`this-> m`访问的,除了你不必写`this->`.也就是说,据我所知,我们在星期一讨论了lambda的成员捕获,并没有很好的解决方案. (4认同)
  • 那太傻了.我无法想象为什么他们认为这是个好主意. (3认同)
  • @MooingDuck:一致性.假设我们从第一个lambda的主体调用非静态成员函数:`f();`.你期望在`*this`或'*this`的副本上调用成员函数吗? (2认同)
  • C++ 14任意表达式捕获功能应该通过允许按值捕获并同时为其赋予不同的名称来解决此问题,从而避免不一致. (2认同)

小智 12

是的,只需编写[<new name>=<your class field>]构造即可。例如:

class MyClass {
    int a;
    void foo() {
        auto my_lambda = [a_by_val=a] {
            // do something with a_by_val
        }

        my_lambda();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 捕获初始化器是 C+14 特性,问题被标记为 C++11。 (2认同)