gpt4 book ai didi

c++ - 理解可变捕获

转载 作者:行者123 更新时间:2023-11-30 01:13:46 27 4
gpt4 key购买 nike

如果我理解正确(我的来源是第 5 版 C++ Primer 第 395 页),mutable 可以从 中修改捕获的变量 lambda 。两件事我不明白:

  1. 这与通过引用捕获有何不同?而且,如果通过引用捕获是底层发生的事情,那么 mutable 的目的是什么?只是一个语法糖?

  2. 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 被评估后,您只是在修改变量的本地拷贝(并且您可以访问此拷贝,即使原始变量已消失)。
  • 使用 & 不会创建原始变量的拷贝,允许您修改它(原始变量),但允许您在“销毁”后访问此变量。

关于c++ - 理解可变捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31317478/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com