You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ Lambda默认值捕获[=]行为不符合预期的技术咨询

关于Lambda表达式[=]值捕获的困惑解答

我是C++编程新手,对Lambda的默认值捕获[=]感到困惑。根据文档说明,[=]应隐式按值捕获Lambda内部使用的自动变量,但以下程序显示被捕获的变量实际被修改,而非创建副本。

= (implicitly capture the used automatic variables by copy).

程序代码

#include <iostream>
#include <atomic>
 
class A {
 public:
  A() : value_{0} {}
  
  void increase() {
    auto inc = [=](){
      value_++;
    };
    
    inc();
  }
  
  int value_;
};

int main()
{
   A a;
   
   std::cout << "value before: " << a.value_ << std::endl;
   
   a.increase();
   
   std::cout << "value after: " << a.value_ << std::endl;
}

程序输出

value before: 0
value after: 1

问题解析

这里的核心误区是对“自动变量”的理解:value_是类的成员变量,不是当前函数的自动变量。在非静态成员函数increase()中,直接访问value_等价于this->value_——Lambda里并没有直接捕获value_,而是捕获了this指针(按值捕获)。

[=]捕获的是当前作用域下的自动变量,这里的自动变量就是this指针本身。虽然捕获的是this的副本,但这个副本依然指向原对象的实例,所以Lambda中对value_的修改,本质是通过this指针操作原对象的成员变量,自然会改变原对象的值。

解决方案

如果想要真正按值捕获成员变量,有两种常见方式:

  1. 显式捕获成员变量的局部副本
    void increase() {
      auto val_copy = value_;
      auto inc = [=](){
        val_copy++; // 修改的是局部副本,不影响原对象的value_
      };
      inc();
    }
    
  2. 捕获整个对象的副本(C++11及以上)
    void increase() {
      auto inc = [=, *this](){
        value_++; // 修改的是对象副本的成员变量,原对象不受影响
      };
      inc();
    }
    

内容的提问来源于stack exchange,提问作者Eric Sun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 20:30:49