30

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

4

3 回答 3

40

不,不能按值捕获数据成员。一个 lambda 只能捕获两种东西:

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

正如 ildjarn 在评论中所指出的,您可以使用数据成员的值的副本创建一个局部变量,并按值捕获该局部变量。

我会争辩说,如果允许对数据成员进行显式按值捕获,这可能会令人困惑,因为显式捕获的行为与隐式捕获的行为不同。例如,给定一个int名为的可访问数据成员m,以下会产生不同的结果会很奇怪:

[=] () mutable { m = 1; } // we modify this->m
[=m]() mutable { m = 1; } // we modify the copy of m that was captured
于 2012-10-17T22:16:51.900 回答
13

是的,只需编写[<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();
    }
}
于 2017-02-03T21:44:11.850 回答
-6

C++ 是一种速度语言,语言设计中最重要的事情之一就是性能。如果标准设计人员想要实现一种通过值捕获类的所有变量的方法,请考虑一个非常大的类,然后说你想按值捕获它们吗?甚至要捕获在函数(包括)中声明的所有变量,this也有两种方法:

  • 按值:在函数中定义的变量,保留在堆栈中,因此它们不能是多兆字节,但使用堆的类vector仍然可能很大。所以要小心使用它!

  • 通过引用:实际上保存堆栈指针。

因此,您会看到没有有效的方法来捕获具有值的类的所有变量,但是您可以在函数中制作该类的本地副本,然后通过引用捕获它!

于 2012-10-17T22:22:16.840 回答