Reputation: 3084
To demonstrate the problem, let me present a short code -
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.
}
In above code, an CustomType
type object is constructed for which copy constructor is deleted. So I must pass it by reference everywhere, or create it from scratch in relevant scope. However for 1 scenario I'm currently dealing with, it is not quite possible to create it in relevant scope which is inside std::thread
's execution method.
What I'm afraid of is obj
might be destructed before std::thread
even completes its job and then I've no idea what's going to happen. So how should I solve this problem of extending it's scope to std::thread's lambda.
Upvotes: 0
Views: 126
Reputation: 44238
Btw your code is incorrect, you do not pass your object, so your code should be instead:
auto obj = getCustomTypeObj();
std::thread([](customType &obj) {
// some delay
obj.doSomething();
obj.close();
// can now be destructed
}, std::ref( obj ) ).detach();
To avoid issue with object lifetime pass your object to the lambda or function by value and move your object there:
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
now lambda or function owns that object and it will be destroyed at the end of the function. Here is the live example, I just used std::unique_ptr
there instead of customType
as type that has copying disabled to validate that moving works.
Upvotes: 3