Lambda捕获对象的生命周期是否与Lambda一致?线程场景答疑
关于Lambda按值捕获与线程的疑问
我一直以为lambda只是函数指针,但从未认真使用过捕获语句。若创建一个按值捕获的lambda,将其移动到完全独立的线程中,且不保留lambda所用的原对象,lambda是否会保留这些拷贝?以下代码中,线程执行时会打印“Success”、“Failure”还是解引用悬空指针?
std::thread createThread() { std::string str("Success"); auto func = [=](){ printf("%s", str.c_str()); }; str = "Failure"; return std::thread(func); } int main() { std::thread thread = createThread(); thread.join(); // 假设线程在此之前不执行任何操作... // 会打印"Success"、"Failure"还是解引用悬空指针? return 0; }
解答
首先纠正一个误解:Lambda不是函数指针,它是带有 operator() 的匿名类实例,捕获语句的本质是给这个匿名类添加成员变量,并在创建Lambda实例时完成初始化。
针对你的问题细节:
- 按值捕获的Lambda会在创建时(也就是执行
auto func = [=](){...};这一行),对捕获的变量做一份拷贝,并将这份拷贝存储在Lambda对象内部。 - 后续修改原变量
str = "Failure";只会改变原字符串对象,完全不会影响Lambda内部已经拷贝完成的那份str。 - 当你把Lambda传递给
std::thread时,线程会接管这个Lambda对象(或其拷贝),Lambda内部的字符串拷贝会和线程生命周期绑定,直到线程执行结束才会销毁。
所以最终线程会打印Success,既不会输出Failure,也不会出现解引用悬空指针的问题。
内容的提问来源于stack exchange,提问作者Anne Quinn
相关产品推荐
相关产品推荐

