You're either transferring ownership - or you're not. If you want to transfer, then you shouldn't care if Bar
can throw and kill your object:
// i do not care what bar does with ptr, i am done with it
bar(std::move(ptr));
If you might want to retain ownership maybe, then transferring ownserhip is the wrong solution. Either you want to pass your unique_ptr
by reference, or maybe just pull out the raw pointer, or maybe even just use a shared_ptr
. It depends on your use-case. But there's no half-way ownership transfer.
Here are some examples. Which is preferred is entirely up to you:
bar(std::unique_ptr<Data>& ptr) {
// not transferring, caller still owns the data
something_that_might_throw();
something_that_might_not();
// ok got here?
std::unique_ptr<Data> myPtr = std::move(ptr);
// MINE NOW!!!
}
The above is "the ONLY exception safe solution to moving a unique_ptr into a container in an exception safe manner with a strong guarantee that the system won't be corrupted" (from MGetz)
Or:
bar(Data* ptr) {
// it really doesn't matter, caller always owns the data
// just don't go doing something like this
std::unique_ptr<Data> awful_idea(ptr);
// now two separate people both think they own the data
// and will both try to delete it. That'll work the first time...
}
Or a strictly better version so you can't mess it up unless you try really hard
bar(Data& data) {
// well clearly the caller owns it
}
Or:
bar(std::shared_ptr<Data> ptr) {
// we both share the data
// it won't get deleted until both bar() and caller delete it
}