C++ lambda值捕获变量不加mutable可正常编译原因求解
问题原理说明
首先你对lambda与mutable的规则存在一点误解:《C++ Primer》中说明的是修改值捕获的变量才需要添加mutable关键字,只读访问值捕获的变量不需要任何额外修饰。
lambda的底层实现逻辑可以很好解释这个现象:
- 编译器会把lambda表达式翻译成一个匿名的可调用类对象,你通过值捕获的变量,会变成这个匿名类的私有成员变量
- 默认情况下,这个匿名类的
operator()调用运算符是被const修饰的成员函数,因此在函数体内不允许修改类的普通成员变量 - 添加
mutable关键字的作用,就是告诉编译器不要给这个operator()加const修饰,允许修改类的成员变量
对应你的两个测试用例:
无mutable的case1
//case1: int val = 5; auto f1 = [val]() {return ++val;}; cout << f1() <<endl;
++val是对值捕获的val成员做自增修改,触发了const成员函数的修改限制,因此编译失败,符合规则预期。
无mutable的case2
//case2: int val = 5; auto f2 = [val]() {return val+5;}; cout << f2() <<endl;
val+5只是读取val成员的值做算术运算,完全没有修改val本身,const成员函数本身就允许读取普通成员的值,因此不需要加mutable也可以正常编译运行。
你可以做个验证:如果在case2的lambda体内加入任何修改val的逻辑,比如val = 10;,不加mutable同样会编译报错。
内容的提问来源于stack exchange,提问作者peteryoung
相关产品推荐
相关产品推荐

