move is redundant.
I would do this:
void takeOwnership(std::unique_ptr<MyObject> nowItsReallyMyObject) { myObjects.emplace_back(std::move(nowItsReallyMyObject)); }
because I would like to move the unique_ptr semantics as unique_ptr as possible.
I can write this utility function:
template<class T> std::unique_ptr<T> wrap_in_unique( T* t ) { return std::unique_ptr<T>(t); }
so that callers can:
foo.takeOwnership(wrap_in_unique(some_ptr));
but even better, then you can infer the boundaries of the unique_ptr semantics as much as possible.
I could even do:
template<class T> std::unique_ptr<T> wrap_in_unique( T*&& t ) { auto* tmp = t; t = 0; return std::unique_ptr<T>(tmp); } template<class T> std::unique_ptr<T> wrap_in_unique( std::unique_ptr<T> t ) { return std::move(t); }
which allows callers to easily switch to T* in unique_ptr . All of their T* → unique_ptr<T> now wrapped in std::move and the zeros of the source pointer.
So if they had
struct I_am_legacy { T* I_own_this = 0; void GiveMyStuffTo( SomeClass& sc ) { sc.takeOwnership( wrap_in_unique(std::move(I_own_this)) ); } };
code can be converted to:
struct I_am_legacy { std::unique_ptr<T> I_own_this; void GiveMyStuffTo( SomeClass& sc ) { sc.takeOwnership( wrap_in_unique(std::move(I_own_this)) ); } };
and it still compiles and works the same way. (Other interactions with I_own_this may change, but part of it will already be I_own_this compatible).
Yakk source share