将 std::unique_ptr 插入 std::set

Inserting std::unique_ptr into std::set

将用 std::make_unique() 制作的 std::unique_ptr 插入 std::set 的最佳方法是什么? insert()emplace() 都可以,但哪个更好?

unique_ptr 的实施方式(仅移动,而非复制)可防止您担心的这种情况。但是创建其他的:

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 

https://godbolt.org/z/3Gfoo7

不管你是否插入或放置它总是通过移动语义发生,即使你s.insert( std::make_unique<X>(1) ),那是一个移动。

在此示例中,3 和 6 从未进入集合,即使像示例中的最后两行 p7 或 p2 一样移动了两次,它们在 inserted/emplaced 之后仍将为“空”在集合中。