Search code examples
c++11vectorbackemplace

C++ vectors: emplace_back vs. push_back


Why is the method emplace_back() necessary at all?

Why can compiler constructors not simply use the faster "create at end" way, when implementing push_back()? What part of the C++ standard prohibits that? What would be the problem in adjusting this part of the standard instead of introducing still another method? As far as I can see, the anonymous object constructed, copied, then deleted has no further life or purpose afterwards.

What is the merit of having two completely equivalent methods, one faster, the other more commonly known and used? Or IS there a difference?


Solution

  • The creation, copying and destruction of the temporary object may have side effects, so the compiler is not allowed to generally skip them even if it is aware that the call to push_back does not cause any other use of the temporary object. This way push_back with a temporary as argument may behave differently than the equivalent emplace_back directly from the constructor arguments. If the compiler realizes that there are no side effects, it can of course optimize a push_back call to the same machine code it would emit for an equivalent emplace_back call.

    Also, push_back allows for list initialization of the temporary object in its argument, while emplace_back always uses (non-list) direct initialization. So some uses of push_back with a temporary are not valid for emplace_back.

    Furthermore, push_back has been there since the beginning of standardized C++ and earlier, but variadic templates exists only since C++11. So it wouldn't have been possible to specify emplace_back before C++11. It would have needed to be limited to some arbitrary finite number of arguments. Also without C++11 forwarding references it doesn't work out so nicely either.

    If you don't need to support anything before C++11 then you can almost always use emplace_back and ignore push_back.