Modern Effective C++ - Using emplace instead of push

In order to add elements to a STL container, most of the containers provide two kinds of APIs-
  • push / insert
  • emplace 

Though the outcomes of both the APIs are the same, the mechanisms they use and the performance characteristics are different.

Depending if the object to be added is Lvalue or Rvalue, push and insert either copies or moves the object into the container. Emplace creates the object in place (within the container itself).

This makes emplacement process much faster than insert or push. You might think std::move  is faster than copying and hence we should use std::move, instead of learning a new insert mechanism. But consider the below class.


But this class has no heap member variables. So even if you move the variable to the vector, it is essentially still getting copied. Same is the case when you pass a Rvalue. A temporary object of struct A is created and is then attempted to get moved to the container. Since the class members are in not in heap, they are again copied, and the temporary is destroyed. Hence it's better to create the object in the container itself, as demonstrated on Line 19,.

Using the emplace API is the best choice when an object's utility and lifetime is restricted to the container. We pass the parameters required by the constructor of the object to the emplace function call, and the object's constructor is called on the container's memory. There are no extra calls to either copy or move.

But there are few cases where using emplace is a bit trickier than insert. This includes using the map container containing user defined classes (as values or keys) and a container for async tasks.

As seen in the example std::piecewise_construct, std::make_tuple is used whenever we have to emplace custom class objects in map (or in unordered map). There are other variants for emplace for other containers as well. Eg emplace_front for deque, emplace_hint for map and set.

Emplacement is also effective when the object has a explicit constructor. Have a look at the example below


Since the constructor is marked explicit, when we attempt push_back 2 (on line 14) it cannot be implicitly converted to an object of class A. This line will fail to compile if un-commented. However when emplace is called, the constructor is called within the vector, and the object get successfully created and stored in the vector, vecA.

Reference - Effective Modern C++ by Scott Meyers


Modern Effective C++ - Using emplace instead of push Modern Effective C++ - Using emplace instead of push Reviewed by zeroingTheDot on June 01, 2018 Rating: 5

No comments:

Powered by Blogger.