我有这个代码:
int i = 0;
[&i](){i++;}();
但我可以省略 i 并使用:
[&](){i++;}();
指定的目的是&i
什么?(同样=var
和=
)。它是否影响编译时间或运行时性能?
&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
该&i
方法由语言提供以限制捕获的变量的数量。C++ 让您可以完全控制捕获的变量,例如要捕获哪些特定变量、如何捕获(按值或引用)。
与i
and的推理相同=
:
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
希望有帮助。
有时您可能希望以不同的方式捕获不同的变量:
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
这就是为什么可以使用更详细的语法的原因。
此功能与性能无关,它与可读性和可维护性有关。当您使用一揽子捕获语法时[&]
,[=]
它会掩盖原始方法和 lambda 主体之间共享的状态。如果开发人员错误地假定未捕获值而确实捕获了值,这可能会导致方法中的维护问题。拥有一个捕获子句使得 lambda 所依赖的状态更加明确。
指定 &i 的目的是什么?(类似地 =var 和 =)。它是否影响编译时间或运行时性能?
您可以指定是按引用还是按值捕获值。Using[&]
指定您要通过引用捕获所有内容,但您也可以编写 lambda 来执行以下操作:
[=, &i, &j]()
这表示按价值捕获所有内容,但捕获i
和j
引用除外。
在您的特定情况下,这没有用-您可以只说通过引用捕获所有内容,编译器将确定您正在使用i
并通过引用捕获它-但是当您处理要捕获的多个变量时,C++ 允许您控制如何单独捕获每个。
如果您列出要捕获的变量,那么您就明确了您想要的内容。如果你使用了你不想使用的东西(你没有捕获它),你会得到一个编译器错误。这可能是一件好事(你在实现中犯了一个真正的错误)或一件坏事(你只是忘记列出变量)。
这真的取决于特定的场景。我希望 lambda 越复杂和/或包含范围越复杂,就越能明确您捕获的内容。
还有一个额外的点,那就是混合按值捕获和按引用捕获 - 你必须至少在其中一个中明确。例子:
int i, j, k;
auto f = [=, &i]() { /* code which can read i, j and k but can only modify i */ };