std::thread执行operator()时vector为空的问题及解决方案咨询
问题解决方法
你的核心问题是栈上的PrintStringManager对象在f()作用域结束时被提前析构,导致线程执行时访问的对象已经失效。下面是几种不用将对象设为静态的简单方案:
1. 用std::move把PrintStringManager转移到线程中
这完全符合你提到的思路,可行且简单。创建线程时,通过std::move将psm的所有权转移给线程内部的可调用对象。此时原作用域中的psm会变成“已转移”的空状态,但线程里的实例会完整保留原vector的数据,不受原对象析构的影响。
示例代码:
void f() { PrintStringManager psm({"str1", "str2", "str3"}); // 初始化时vector有3个元素 std::thread t(std::move(psm)); // 转移psm所有权到线程 t.join(); // 根据需求选择join或detach }
2. 直接在线程构造时创建PrintStringManager
跳过栈上的临时对象,直接把PrintStringManager的构造作为线程的参数,这样对象会直接被构造到线程内部的存储区域,完全脱离f()的作用域,自然不会提前析构。
示例代码:
void f() { // 直接在线程参数中构造对象,所有权归线程 std::thread t(PrintStringManager({"str1", "str2", "str3"})); t.join(); }
3. 用智能指针托管对象
如果需要更灵活的生命周期控制,可以把PrintStringManager放在堆上,用std::unique_ptr管理,然后通过移动捕获把指针转移给线程的lambda。只要线程还在运行,智能指针就会维持对象的生命周期。
示例代码:
void f() { auto psm_ptr = std::make_unique<PrintStringManager>({"str1", "str2", "str3"}); std::thread t([psm = std::move(psm_ptr)]() { (*psm)(); // 调用对象的operator() }); t.join(); }
内容的提问来源于stack exchange,提问作者eniac
相关产品推荐
相关产品推荐

