为了证明这个问题,让我提出一个简短的代码 -
void someMethod() {
// CustomType obj;
const auto obj = getCustomTypeObj();
std::thread([](customType &obj) {
// some delay
obj.doSomething();
obj.close();
// can now be destructed
}).detach();
// similarly for std::async
std::async(std::launch::async, [](customType &obj){
obj.doSomething();
obj.close();
}
// there might not be any use of obj here
// should not be destructed here because std::thread might not get it.
}
在上面的代码中,构造了一个CustomType
类型的对象,为其删除了复制构造函数。所以我必须在任何地方通过引用传递它,或者在相关范围内从头开始创建它。但是,对于我目前正在处理的1个场景,不太可能在std::thread
执行方法内的相关范围内创建它。
我害怕的obj
可能会在std::thread
完成工作之前被破坏,然后我不知道会发生什么。那么我该如何解决将它的范围扩展到std :: thread' lambda的问题。
答案 0 :(得分:3)
如果你的代码不正确,你没有传递你的对象,所以你的代码应该是:
auto obj = getCustomTypeObj();
std::thread([](customType &obj) {
// some delay
obj.doSomething();
obj.close();
// can now be destructed
}, std::ref( obj ) ).detach();
为了避免对象生命周期问题,请将对象传递给lambda或按值运行,并将对象移动到那里:
auto obj = getCustomTypeObj();
std::thread([](customType arg) { // note by value, not reference
// some delay
arg.doSomething();
arg.close();
// arg will be destroyed here
}, std::move( obj ) ).detach(); // object moved
现在lambda或function拥有该对象,它将在函数末尾被销毁。以下是live example,我只使用std::unique_ptr
代替customType
作为禁用复制以验证移动是否有效的类型。