Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

push_back or emplace_back with std::make_unique

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)

like image 506
NHDaly Avatar asked Mar 17 '15 00:03

NHDaly


People also ask

Should I use Emplace_back or Push_back?

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.

Why is Emplace_back faster than Push_back?

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.

What is the use of std :: Make_unique?

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 ".)

Does Emplace_back use move constructor?

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.


1 Answers

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(); 
like image 103
Praetorian Avatar answered Sep 24 '22 12:09

Praetorian