理解可变捕获
Making sense of mutable capture
如果我理解正确的话(我的源代码是 c++ Primer第5版的第395页),mutable
使得可以从lambda
中修改捕获的变量。有两件事我不明白:
-
这与通过引用捕获有什么不同?如果通过参考捕获是下面发生的事情,那么
mutable
的目的是什么?只是一个语法糖? -
如果
mutable
能以每个变量为单位来应用岂不是更有帮助?
mutable
允许您修改在lambda作用域之外定义的变量,但是您对这些变量所做的任何更改都不会扩展到初始变量:
auto f1 = [=] () mutable { n += 4; return n ; } ;
auto f2 = [&] () { n += 4; return n ; } ;
std::cout << f1 () << ' ' ; // Call to f1, modify n inside f1
std::cout << n << ' ' ; // But not in main
// 2nd call to f1, the value of n inside f1 is the value stored during the first call,
// so 8 (the output will be 8 + 4)
std::cout << f1 () << ' ' ;
std::cout << f2 () << ' ' ; // Call to f2, modify n inside f2
std::cout << n << std::endl ; // And in main
输出8 4 12 8 8
另一个区别是,当您使用按值捕获时,值是在计算lambda时捕获的,而不是在调用它时捕获的:
int n = 4 ;
auto f1 = [=] () mutable { return n ; } ; // lambda evaluated, value is 4
auto f2 = [&] () { return n ; } ; // lambda evaluated, reference to n
std::cout << f1 () << ' ' ; // Call to f1, captured value is 4
std::cout << f2 () << ' ' ;
n = 8 ;
std::cout << f1 () << ' ' ; // Call to f1, captured value is still 4
std::cout << f2 () << std::endl ; // Reference to n, so updated value printed
输出:4 4 4 8
最后一个(巨大的)区别是,一旦目标超出作用域,引用捕获的变量就不可用了:
std::function <int ()> f (bool withref) {
int n = 4 ;
if (withref) {
return [&] () { return n ; } ;
}
return [=] () { return n ; } ;
}
auto f1 = f (false) ;
auto f2 = f (true) ;
std::cout << f1 () << ' ' ;
std::cout << f2 () << std::endl ; // Something will go wrong here...
输出:4 1639254944
第二个行为是未定义的。
总结:
- 使用
mutable
允许您修改在函数范围内的值捕获的变量,但是由于该变量在lambda计算时已被复制到另一个内存位置,因此您只修改该变量的本地副本(并且您可以访问该副本,即使原始变量已经消失)。- 使用
&
不会创建原始变量的副本,允许您修改它(原始变量),但允许您在"销毁"后访问该变量。 - 使用
相关文章:
- 没有找到相关文章