mutable允许Lambda修改值捕获的变量副本,使operator()变为非const,但不影响外部变量;对引用捕获无效。

mutable 让 Lambda 能修改值捕获的变量
默认情况下,Lambda 表达式的函数调用运算符是 const 成员函数,哪怕你用 [=] 值捕获了变量,也无法在 Lambda 体内给它赋值。加 mutable 就是为了取消这个限制——它让编译器生成一个非 const 的 operator(),从而允许修改按值捕获的副本。
不加 mutable 就会编译失败
常见错误现象:error: assignment of read-only variable 或类似提示(GCC/Clang),Visual Studio 可能报 C3491: 'x': a by-value capture cannot be modified in a non-mutable lambda。
典型触发场景:
- 想在多次调用中维护内部状态(比如计数器、累加器)
- 需要对捕获的容器做
push_back、sort等就地修改操作 - 配合
std::for_each或std::transform时需更新局部快照
注意:mutable 对引用捕获([&x])无效——引用本来就能改,加不加都一样;它只影响值捕获([x]、[=])的那份拷贝。
立即学习“C++免费学习笔记(深入)”;
参数和性能影响:拷贝一次,改的是副本
mutable 不改变捕获方式,只是放宽了调用约束。值捕获仍会发生一次拷贝,Lambda 内部修改的只是这个副本,不影响外部原始变量。
示例:
int x = 10;
auto f = [=]() mutable {
x = 20; // OK:修改的是捕获的副本
return x;
};
f(); // 返回 20
std::cout << x << "\n"; // 输出仍是 10
如果捕获的是大对象(如 std::vector),mutable 不会额外开销,但反复修改副本可能带来意外的性能或语义问题——比如你以为在复用同一个容器,其实每次都在改新拷贝。
容易忽略的细节:mutable 位置和 const 成员函数冲突
mutable 必须紧挨着参数列表之后、函数体之前,写错位置(比如放在返回类型前)会编译失败。
另外,如果 Lambda 同时被声明为 const(比如作为类成员函数调用时隐式绑定到 const 对象),即使写了 mutable 也无济于事——此时整个调用上下文是 const 的,不能调用非 const 的 operator()。这种情况需要检查外层对象是否 const,或者避免在 const 成员函数里使用需 mutable 的 Lambda。











