haohaolee's blog

nerd以上,geek未满

TIL What the Emplace Operation Is in C++11

There are some new operations added to STL containers in C++11, which include emplace, emplace_hint, emplace_front, emplace_after and emplace_back.

Nearly all containers in STL have this kind of operations except std::array, because it’s immutable. All these operations share the common characteristic, which is ‘constructing elements in containers directly without copy or move’.

Motivation

Since C++11 introduced rvalue-reference and its moveable semantic, although a big improvement on performance, sometimes there are still some redundant copy operations. For instance, say we have:

1
2
vector<tuple<int, double, long double>> v;
v.push_back(make_tuple(2, 3.14, 2.71828));

First, the tuple is a POD, therefore no movable constructor, actually it is obvious you cannot move anything from within a POD object. The above code may make some copies of the tuple which depends on the compiler optimaztion.

Second, even when operating on moveable object, some copies still cannot be avoided. You can move a vector, but you still need copy the internal pointer that holds the resource.

Emplace can do better for this, thanks to variadic template and the perfect forwarding. Instead of the above code, we can do:

1
2
vector<tuple<int, double, long double>> v;
v.emplace_back(2, 3.14, 2.71828);

Here emplace_back will forward all the parameters to some internal function where the vector constructs its elements, just like what a tuple<int, double, long double> t(2, 3.14, 2.71828); does. No copies, no moves, constructs directly.

Another example

1
2
3
4
5
6
7
vector<vector<int>> vec_2d;

// add a vector filled with five ones

vec_2d.push_back(vector<int>(5, 1)); // using push_back, and expect to move

vec_2d.emplace_back(5, 1); //or using emplace_back, constructing it directly

Note you only need provide the parameters for the element’s constructor by order.

Comments