在lambda表达式中指定捕获变量的目的是什么?

tex*_*uce 27 c++ lambda c++11

我有这个代码:

int i = 0;
[&i](){i++;}();
Run Code Online (Sandbox Code Playgroud)

但我可以省略我,只是使用:

[&](){i++;}();
Run Code Online (Sandbox Code Playgroud)

指定的目的是&i什么?(以及类似地=var=).它是否会影响编译时间或运行时性能?

Naw*_*waz 26

&i表示仅i捕获作为引用,同时&表示从范围捕获lambda中使用的所有变量.

int i = 0, j = 10;

[&i]{ i++; j++;}(); //error: j is not captured by reference

[&]{ i++; j++;}(); //ok: both variables are captured by reference
Run Code Online (Sandbox Code Playgroud)

&i方法由语言提供,以限制捕获的变量的数量.C++为您提供对捕获变量的完全控制,包括捕获哪些特定变量,如何捕获(通过值或引用).

同样的推理i=:

int i = 0, j = 10;

[i]{ i++; j++;}(); //error: j is not captured (only i is captured by value)

[=]{ i++; j++;}(); //ok: both variables are captured by value

//more
[&i, j]{ i++; j++;}(); //ok: captured i by reference, j by value
Run Code Online (Sandbox Code Playgroud)

希望有所帮助.

  • 是的,我的问题不是关于它们的区别,我已经知道了.我想知道为什么第一个已经提供,如果第二个已经捕获了所有 (2认同)
  • 并非捕获范围内的所有内容.只是在lambda中使用的东西. (2认同)

Tim*_*lds 21

有时您可能希望以不同方式捕获不同的变量:

std::vector<int> v { 7, 8, 9, 10, 11 };
int n = 3;

//Capture v by reference and n by value:
auto getNth = [&v, n](){ return v[n]; };

//Behavior:
n = 9999;
getNth(); //returns 10 - changing n didn't affect the lambda
v[3] = 42;
getNth(); //returns 42 - changing v did affect the lambda
Run Code Online (Sandbox Code Playgroud)

这就是更详细的语法可用的原因.


Jar*_*Par 17

此功能与可读性和可维护性无关.当您使用毯式捕获语法时[&],[=]它会模糊原始方法和lambda体之间共享的状态.如果开发人员错误地假定某个值未被捕获,则这可能会导致方法中的维护问题.拥有一个capture子句使得它更加明确lambda所依赖的状态.


Ree*_*sey 11

指定&i的目的是什么?(类似地= var和=).它是否会影响编译时间或运行时性能?

您可以指定是通过引用还是按值捕获值.使用[&]指定您希望通过引用捕获所有内容,但您也可以编写执行以下操作的lambda:

[=, &i, &j]()
Run Code Online (Sandbox Code Playgroud)

其中说除了捕获ij引用之外,按值捕获所有内容.

在您的特定情况下,这没有用 - 您可以说通过引用捕获所有内容,编译器将确定您正在使用i并通过引用捕获它 - 但是当您处理捕获的多个变量时,C++允许您控制每个人如何被单独捕获.