C++指定值捕获的lambda表现为引用捕获的问题求解
问题原因解释
你的代码的不符合预期行为完全来自C++ lambda在类内捕获类成员的特殊规则,分两点说明:
- 类非静态成员的访问本质是隐式调用this指针
你在lambda里写的m_property,等价于this->m_property,你用[=]值捕获的时候,捕获的是this指针的副本,而非m_property本身的副本。也就是说lambda内部存储的是当前对象的内存地址,后续所有对m_property的读写都是直接操作原对象的成员:- 你调用
obj.setProperty(5)修改了原对象的m_property,lambda通过存的this指针访问到的自然是修改后的5,不会是你预期的3 - 调用
obj.lmbSet(12)也是直接通过this指针修改原对象的m_property,所以后续call()输出12而非3
如果你确实需要捕获m_property的快照副本,可以用C++14及以上支持的显式初始化捕获写法:[m_capture = m_property],这样就不会受原对象修改的影响。
- 你调用
- 类静态成员不会被lambda捕获
类的静态成员s_fild是类全局共享的,不属于任何实例对象,访问它不需要依赖this指针,也不会被捕获到lambda的存储里,你在lambda里访问的永远是当前的全局静态变量值:你修改Fuu::s_fild = 11之后,lambda自然输出最新的11,不会是你预期的初始值10。
实际运行这段代码的输出为:
test 3 test 5 test 12 static: 10 static: 11
完全符合上述规则推导的结果。
内容的提问来源于stack exchange,提问作者Петр Кусоцкий
相关产品推荐
相关产品推荐

