I am confused about std::maps
's implementation of emplace()
. emplace()
is a variadic template function with the following declaration:
template <class Args...>
iterator emplace( Args&&... args );
As far as I understand, emplace()
completely avoids constructing its value_type
, i.e., std::pair<const key_type,mapped_type>
, and instead constructs the object in-place. I assume this means that the object is constructed only once, the moment that the new map node is created. The object is never copied or moved.
What I don't understand is how std::map
finds the correct place to add the new entry before constructing the key-value pair. As far as I see, std::map
needs access to the key but the key is contained within args
and only accessible after construction of the key-value pair.
I must be misunderstanding some aspect of emplace()
. Does std::map
actually avoid construction of the key-value pair? If so, how does it avoid move/copy operations? Or is there another way to access the key in args
?
emplace
constructs the pair in-place forwarding the arguments to its constructor; it does not avoidelement_type
construction, it just avoids one copy of a useless temporary pair compared toinsert
. In this regard, it's just as for the other containers:emplace
is likeinsert
, but instead if receiving a ready-madeelement_type
to copy or move inside the container, it receives the arguments to constructelement_type
in its target location.To further clarify: if you call
emplace(key, value)
key
andvalue
are copied/moved anyhow when constructing the pair. It's just that, if you didinsert(make_pair(key, value))
, not onlykey
andvalue
would have beem copied/moved when creating the temporary pair argument, but the pair itself would have then needed to be moved in the map node.In that case for an
std::map
there's not much of a problem: first you can construct a node (which contains the pair and the various pointers to other nodes, and has its own allocation on the heap), and then you can put it in the right place in the RB tree (which boils down to just a couple of pointers assignment).