Let me start with background context.
Often time, in server side programming, our function call may go async (i.e. to shift the work to another thread in callback because of IO). So the pattern is function A calls B, B calls C and eventually in many layer deep down in function Z, we may decide to go async.
Function A needs to transfer ownership managed by a unique_ptr by using std::move all the way to function Z. However, move unique_ptr is 40 nsec (vs 20 nsec passing shared_ptr by value or 1 nsec for passing raw pointer). For extremely perf sensitive server application, we may not want to do unique_ptr move through so many layers of functions. For similar reasons, we don't want to use shared_ptr (more importantly shared_ptr always messes up ownership).
To be clear, we can use raw pointers and manage the resource ourselves. We always have that option and it could ultimately be the best option. But for the sake of argument, I think there is another option that I want to get people's opinion on.
So the proposed pattern is to pass raw pointer from the unique_ptr all the way from function A to Z. At function Z where I need to go async, I create a new unique_ptr based on the passed raw pointer and move to the new thread (i.e. I can capture the raw pointer in lambda, and create the new unique_ptr in lambda's body and execute the lambda in new thread). At function A, if there is no exception thrown (i.e. the transfer succeeded), I will call release on unique_ptr so there is no double release. If there is exception, then I will not call release so the caller in A will free the unique_ptr's resource. This way, I avoided a chain of move of unique_ptr and still be able to. See example below.
void Foo1(MyObj* po)
{
auto l =[po](){ auto u = std::unique_ptr<MyObj>(po); };
std::thread t(l);
t.join();
}
int main()
{
auto p1 = std::make_unique<MyObj>();
Foo1(p1.get());
std::cout<<"i am here\n";
p1.release();
}