Based on the answers in these questions here, I know that it is certainly preferred to use c++14's std::make_unique
than to emplace_back(new X)
directly.
That said, is it preferred to call
my_vector.push_back(std::make_unique<Foo>("constructor", "args"));
or
my_vector.emplace_back(std::make_unique<Foo>("constructor", "args"));
That is, should I use push_back
or emplace_back
when adding an std::unique_ptr
constructed from std::make_unique
?
==== EDIT ====
and why? c: <-- (tiny smile)
You should definitely use emplace_back when you need its particular set of skills — for example, emplace_back is your only option when dealing with a deque<mutex> or other non-movable type — but push_back is the appropriate default. One reason is that emplace_back is more work for the compiler.
because emplace_back would construct the object immediately in the vector, while push_back , would first construct an anonymous object and then would copy it to the vector.
make_unique prevents the unspecified-evaluation-order leak triggered by expressions like foo(unique_ptr<X>(new X), unique_ptr<Y>(new Y)) . (Following the advice "never say new " is simpler than "never say new , unless you immediately give it to a named unique_ptr ".)
Calling emplace_back will call the move constructor of std::string when std::move is used, which could save on a copy (so long as that string isn't stored in a SSO buffer). Note that this is essentially the same as push_back in this case.
It doesn't make a difference as far as construction of the new object is concerned; you already have a unique_ptr<Foo>
prvalue (the result of the call to make_unique
) so both push_back
and emplace_back
will call the unique_ptr
move constructor when constructing the element to be appended to the vector
.
If your use case involves accessing the newly constructed element after insertion, then emplace_back
is more convenient since C++17 because it returns a reference to the element. So instead of
my_vector.push_back(std::make_unique<Foo>("constructor", "args")); my_vector.back().do_stuff();
you can write
my_vector.emplace_back(std::make_unique<Foo>("constructor", "args")).do_stuff();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With