What is the best way to insert a std::unique_ptr made with std::make_unique() into a std::set? Both insert() and emplace() work, but which one is better?
What is the best way to insert a std::unique_ptr made with std::make_unique() into a std::set? Both insert() and emplace() work, but which one is better?
The way unique_ptr was implemented ( move-only, not copy ) it prevents that this scenario you are concerned. But create others:
s.insert( std::make_unique<X>(1) ); // SAFE
auto p2 = std::make_unique<X>(2);
s.insert( std::move(p2) ); // also safe
auto p3 = std::make_unique<X>(3);
//s.insert( p3 ); // unsafe, compiler complains
s.emplace( std::make_unique<X>(4) ); // SAFE
auto p5 = std::make_unique<X>(5);
s.emplace( std::move(p5) ); // also safe
auto p6 = std::make_unique<X>(6);
//s.emplace( p6 ); // unsafe on exception, compiler will complain if you uncomment
auto p7 = std::make_unique<X>(7);
s.emplace( std::move(p7) ); // also safe
s.emplace( std::move(p7) ); // insert same agains also "safe", but inserts "null"
s.emplace( std::move(p2) ); // insert "null" again, but nulls are highlanders here
Does not matters if you we inserted or emplaced it always happens thru move semantics, even when you s.insert( std::make_unique<X>(1) ), that is a move.
In this example, 3 and 6 never entered the set and, even after you move it twice like in the last two lines p7 or p2 in the sample, they will be "null" just after inserted/emplaced in the set.