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?
emplaceconstructs the pair in-place forwarding the arguments to its constructor; it does not avoidelement_typeconstruction, it just avoids one copy of a useless temporary pair compared toinsert. In this regard, it's just as for the other containers:emplaceis likeinsert, but instead if receiving a ready-madeelement_typeto copy or move inside the container, it receives the arguments to constructelement_typein its target location.To further clarify: if you call
emplace(key, value)keyandvalueare copied/moved anyhow when constructing the pair. It's just that, if you didinsert(make_pair(key, value)), not onlykeyandvaluewould 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::mapthere'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).