This was a source of confusion for me, but std::unordered_map::try_emplace takes the key and variable arguments for the constructor of the value(mapped) type, however ::emplace is supposed to take an std::pair<key, value>:
In addition, try_emplace treats the key and the arguments to the mapped_type separately, unlike emplace, which requires the arguments to construct a value_type (that is, a std::pair).
Ok, that is confusing. Why is it that the function signature is:
template< class... Args >
std::pair<iterator, bool> emplace( Args&&... args );
Why the multiple arguments if you're required to construct an std::pair<key, value> as described above?
In general, this is because
emplaceis really designed to forward the parameters to the constructor of the object. (It can be the copy constructor, in which case you use only one parameter with the value (or r-value0 you want to store, but it doesn't need to be).In this particular example, it the value is
std::pairso it is less useful.Example:
https://godbolt.org/z/PYx51jT4x
Some people do not recommend using emplace for some containers because there is really not much gain and it can be misleading, because many times the value will be constructed anyway before knowing "where" in needs to be and then copied there, instead of really emplaced.
Take a look at Meyer's book, "Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14"
Not sure now if
unordered_setis one of these.