C++ lambda函数作用域、生命周期及std::move对回收的影响咨询
lambda作用域与生命周期基础
lambda表达式本质是C编译器自动生成的匿名仿类类型的临时对象,它的生命周期遵循普通C对象的RAII规则,没有特殊的额外机制。
第一个代码片段:switch作用域外lambda是否存活
对应代码:
{ // ... std::function<int()> action; switch (A) { case 0: action = []()->int { return 1; }; break; case 1: action = []()->int { return 2; }; break; default: break; } // ... }
你可以完全放心在switch作用域外使用action,lambda是存活可用的:
- switch case内创建的lambda是临时对象,赋值给
action的时候,std::function会把这个临时lambda复制/移动到自身内部的存储空间中 - 原始的临时lambda在赋值语句结束后就会自动析构,但
std::function内部保存的lambda副本,生命周期和action完全绑定。action定义在switch的上层作用域,只要action本身没有被析构,内部的lambda就一直存活。
lambda的回收机制
lambda就是普通的C栈对象,没有独立的回收机制,完全遵循C的生命周期规则:
- 如果是直接生成的临时lambda对象(比如赋值时直接写lambda表达式没有存到变量),会在所在的完整表达式执行结束后自动析构
- 如果lambda被存到其他对象中(包括
auto定义的lambda变量、std::function、被其他lambda捕获等),它的生命周期就和持有它的宿主对象完全绑定,宿主对象析构时,内部保存的lambda会自动被析构回收,不需要手动管理。
第二个代码片段:加std::move会不会导致无法回收
对应代码:
void funct(){ // ... std::function<int()> action; switch (A) { case 0: action = std::move([]()->int { return 1; }); break; case 1: action = std::move([]()->int { return 2; }); break; default: break; } // ... }
不存在无法自动回收的问题:
- 这里加
std::move本质是多此一举,lambda临时对象本身就是右值,不加std::move也会调用移动构造把lambda转移到action内部,两者效果没有区别 action是funct内的局部栈变量,funct执行结束栈帧回收时,action会自动析构,其内部持有的lambda对象也会跟着被析构,完全不会出现泄漏或者无法回收的情况。std::move仅仅是转移对象的所有权,不会改变对象和宿主的生命周期绑定规则。
内容的提问来源于stack exchange,提问作者jojo_Aero_smith_the_dummy
相关产品推荐
相关产品推荐

