mutable允许Lambda修改值捕获的变量副本,使operator()变为非const,但不影响外部变量;对引用捕获无效。
默认情况下,Lambda 表达式的函数调用运算符是 const 成员函数,哪怕你用 [=] 值捕获了变量,也无法在 Lambda 体内给它赋值。加 mutable 就是为了取消这个限制——它让编译器生成一个非 const 的 operator(),从而允许修改按值捕获的副本。
常见错误现象: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]、[=])的那份拷贝。
mutable 不改变捕获方式,只是放宽了调用约束。值捕获仍会发生一次拷贝,Lambda 内部修改的只是这个副本,不影响外部原始变量。
示例:
int x = 10;
auto f = [=]() mutable {
x = 20; // OK:修改的是捕获的副本
return x;
};
f(); // 返回 20
std::cout << x << "\n"; // 输出仍是 10
如果捕获的是大对象(如 std::vector),mutable 不会额外开销,但反复修改副本可能带来意外的性能或语义问题——比如你以为在复用同一个容器,其实每次都在改新拷贝。
mutable 必须紧挨着参数列表之后、函数体之前,写错位置(比如放在返回类型前)会编译失败。
另外,如果 Lambda 同时被声明为 const(比如作为类成员函数调用时隐式绑定到 const 对象),即使写了 mutable 也无济于事——此时整个调用上下文是 const 的,不能调用非 const 的 operator()。这种情况需要检查外层对象是否 const,或者避免在 const 成员函数里使用需 mutable 的 Lambda。