在Lambda函数中,使用[=]和[&]有什么区别吗?

45

最近我在学习c++11中的lambda函数。但是我不知道[=][&]有没有区别。如果有区别的话,具体是什么?

并且,在这两种情况下,lambda函数体中的this是否有区别?

3个回答

80

区别在于如何捕获值

  • & 通过引用进行捕获
  • = 通过值进行捕获

快速示例

int x = 1;
auto valueLambda = [=]() { cout << x << endl; };
auto refLambda = [&]() { cout << x << endl; };
x = 13;
valueLambda();
refLambda();

这段代码将会打印

1
13

第一个 lambda 在定义 valueLambda 时通过值捕获了 x。因此它得到了当前的值 1。但是 refLambda 捕获了对本地变量的引用,因此它看到的是最新的值。


1
谢谢。那我的第二个问题呢?如果Lambda函数在一个类中,lambda体内的this是否有任何不同? - pktangyue
1
@pktangyue 这不会影响对 this 的捕获,因为 this 总是按值捕获的。 - JaredPar
1
@JaredPar 我不明白为什么valueLambda()会打印1,尽管它是按值捕获的,而在调用valueLambda之前x的值已经被更改为13? - gaurav
1
@gaurav valueLambda() 捕获的是定义 valueLambda() 时 x 的值,而不是调用时的值。x = 13; 是在定义 valueLambda() 之后。 - Harvey

15
  • & 表示“引用捕获”。
  • = 表示“值捕获”。

我在这里回复是想指出一件事:

this 指针始终以值的方式进行捕获。在 C++11 中,这意味着如果你想要捕获类中变量的一个副本,比如 this->a,实际上它会被以引用的方式进行捕获。为什么呢?

考虑:

[this]() { ++this->a; }

this被按值捕获,但这是一个指针,所以a通过this引用。

如果您想要成员变量的副本,在C++11中,可以像这样做:


auto copy = this->a;
[copy]() mutable { ++copy; }

注意这个警告,因为它并不直观,除非你深思熟虑。


2
另外,如果你要修改Lambda内部的副本,你必须将其声明为可变的:copy mutable { ++copy; } - Gerard097

0

JaredPar已经回答了第一个问题。

对于您的第二个问题,lambda体中的this与其包含类的this相同。以下示例来自标准文件。

struct S1 {
  int x, y;
  int operator()(int);
  void f() {
    [=]()->int {
      return operator()(this->x + y); 
      // equivalent to S1::operator()(this->x + (*this).y)
      // this has type S1*
    };
  }
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接