销毁Lambda表达式后调用其转换的函数指针是否合法?
Lambda销毁后调用相关函数的合法性分析
问题1:销毁Lambda表达式后调用该lambda函数是否合法?
如果直接调用已销毁的Lambda闭包实例(比如出作用域后的lambda变量),这属于访问已销毁对象的行为,不合法,会触发未定义行为。但你的代码里并没有直接调用这个已销毁的闭包实例,而是做了函数指针转换,所以这个场景和你的代码逻辑不直接相关。
问题2:销毁Lambda表达式后调用f_ptr()是否合法?
完全合法,核心原因如下:
- 你使用的是无捕获Lambda(
[]为空),这类Lambda可以转换为对应的函数指针,转换后得到的指针指向编译器为该Lambda生成的静态全局函数。 - 这个静态函数的生命周期和整个程序运行期一致,不会随Lambda闭包实例的销毁而消失。
- 代码中的
lambda变量是闭包实例,出作用域后确实会被销毁,但f_ptr保存的是指向静态函数的指针,和闭包实例的生命周期完全无关,因此后续调用f_ptr()是安全且符合C++标准的。
代码细节说明
针对你给出的代码片段:
void (*f_ptr)() = nullptr; { auto lambda = +[](){some_func1(); some_func2(); some_func3();}; f_ptr = lambda; } f_ptr();
这里的+是显式触发Lambda到函数指针的转换(无捕获Lambda本身也支持隐式转换,+只是让转换更直观)。编译器生成的静态函数会包含some_func1()、some_func2()、some_func3()的调用逻辑,只要这些函数在调用时本身是有效的,f_ptr()的调用就不会有问题。
内容的提问来源于stack exchange,提问作者Xeenych Xeenych
相关产品推荐
相关产品推荐

