在类中使用时,lambda 捕获列表中的 [this] 和 [&] 是否等效?

Kat*_*tie 8 c++ lambda

在下面的示例中,在捕获列表中使用 [this] 与在捕获列表中使用按引用捕获 [&](如图所示)有何区别?我都尝试过,它们产生相同的输出。

#include <iostream>                                                          

class Test {                                                                 
public:                                                                      
   int x = 2;                                                                
   void test1(void) { std::cout << "test1" << std::endl; };                  

    void test_lambda(void) {                                                 
        auto lambda = [&] () {                                               
            std::cout << "x: " << x << " y: " << y << " z: " << z << std::endl;
            this->test1();                                                         
        };                                                                   

        lambda();                                                            
    }                                                                        

protected:                                                                   
   int y = 3;                                                                

private:                                                                     
   int z = 4;                                                                
};                                                                           

int main() {                                                                 
    Test t;                                                                  
    t.test_lambda();                                                         
}  
Run Code Online (Sandbox Code Playgroud)

Stroustrop 在 C++ 编程语言中说道:

    Members are always captured by reference. That is, [this] implies that members are accessed through this rather than copied into the lambda. 
Run Code Online (Sandbox Code Playgroud)

这似乎暗示它们可能意味着同一件事。如果是这样的话,我们为什么需要[这个]?

Dan*_*man 5

根据cppreference

[&] 通过引用捕获 lambda 主体中使用的所有自动变量,并通过引用捕获当前对象(如果存在)

而使用 [this] 将仅捕获this指针。

当作用域中有自动变量时,这会有所不同,例如:

struct Test {
  void run() {
    int y = 2;

    // all automatic variables are accessible, both local and members
    auto l1 = [&](){ cout << x << " " << y << endl; };
    l1();

    // y is not accessible, x is only because it's a member
    auto l2 = [this]() { cout << this->x << endl; };
    l2();
  }

  int x = 1;
};

int main() {
  Test t;
  t.run();
}
Run Code Online (Sandbox Code Playgroud)

那么,我们为什么需要它?

允许捕获 [this] 与允许捕获任何其他指针相同。

为什么不一直捕获所有自动变量呢?有几个原因,包括:

  • 封装:有时,您不希望 lambda 熟悉其他值
  • 灵活性:有时,我们需要复制一些值并通过引用传递其中一些值

注意:使用 & 捕获所有自动变量不会带来额外的性能成本,因为编译器仅传递我们在 lambda 内使用的变量。