“值捕获”和“引用捕获”

在C++中,Lambda表达式可以捕获外部作用域中的变量,这样就可以在Lambda表达式的函数体中使用这些变量。捕获可以通过值或引用进行,这两种方式有着不同的行为和用途。

  1. 值捕获(Value Capture):当一个外部变量被Lambda表达式通过值捕获时,该变量的当前值会被复制到Lambda表达式中。这意味着,即使在Lambda表达式创建后,外部变量的值发生了改变,这个改变也不会影响到Lambda表达式中的值。同样,如果Lambda表达式改变了捕获的变量的值,这个改变也不会影响到外部的变量。
int x = 0;
auto lambda = [x]() { return x+1; };  // x被值捕获
x = 5;
std::cout << lambda() << std::endl;  // 输出1,而不是6
  1. 引用捕获(Reference Capture):当一个外部变量被Lambda表达式通过引用捕获时,Lambda表达式实际上保留了对该变量的引用,而不是复制它的值。这意味着,如果在Lambda表达式创建后,外部变量的值发生了改变,这个改变会影响到Lambda表达式中的值。同样,如果Lambda表达式改变了捕获的变量的值,这个改变也会影响到外部的变量。
int x = 0;
auto lambda = [&x]() { return x+1; };  // x被引用捕获
x = 5;
std::cout << lambda() << std::endl;  // 输出6

注意:在使用引用捕获时,需要确保Lambda表达式使用的时候,被捕获的变量仍然存在。如果在Lambda表达式创建后,被捕获的变量已经被销毁,那么在Lambda表达式中使用这个变量将会导致未定义的行为。

 

这段代码中包含两个Lambda表达式,一个使用引用捕获,另一个使用值捕获。这两个Lambda表达式都会打印变量a、b和c的值,然后增加变量a的值。

  1. 第一个Lambda表达式使用引用捕获(&),这意味着它会直接操作原始变量a、b和c。在这个Lambda表达式中,它首先打印变量a的值(100),然后打印变量b和c的和(500),然后增加变量a的值。因此,执行这个Lambda表达式后,变量a的值变为101。

  2. 然后,主程序打印变量a的值,此时a的值为101。

  3. 第二个Lambda表达式使用值捕获(=),这意味着它会复制变量a、b和c的值,然后在这些复制的值上进行操作。然而,这个Lambda表达式被声明为mutable,这意味着它可以修改捕获的变量的值(在这种情况下,是复制的值,而不是原始的值)。在这个Lambda表达式中,它首先打印变量a的值(101,因为这是在Lambda表达式创建时a的值),然后打印变量b和c的和(500),然后增加变量a的值。但是,因为这是值捕获,所以这个增加不会影响主程序中的变量a。

所以,这段代码的输出应该是:

100 500
101
101 500

注意:这里假设qDebug()函数的行为类似于C++的std::cout,即它会打印传递给它的值,然后在值之间添加一个空格,并在每个调用后添加一个换行符

解释它首先打印变量a的值(101,因为这是在Lambda表达式创建时a的值)

在C++中,当你创建一个使用值捕获的Lambda表达式时,它会立即复制所有捕获的变量的当前值。这些复制的值被存储在Lambda表达式中,并在Lambda表达式的函数体中使用。

在你的代码中,第二个Lambda表达式在创建时捕获了变量a、b和c的值。这时,变量a的值是101,因为在第一个Lambda表达式中,a的值被增加了1。因此,当第二个Lambda表达式打印变量a的值时,它打印的是101,这是在Lambda表达式创建时a的值。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值