In C++17, std::map
and std::unordered_map
got a new member-function template: try_emplace()
. This new addition, proposed in n4279, behaves similarly to emplace()
, but has the following advantages:
try_emplace()
does not move from rvalue arguments if the insertion does not happen. This is useful when manipulating maps whose values are move-only types, such as std::unique_ptr
.try_emplace()
treats the key and the arguments to the mapped_type
separately, which makes it somewhat more intuitive than generic mutators that are expressed in terms of value_type
(which is std::pair
).Given the above advantages, would you ever use emplace()
from C++11 instead of try_emplace()
from C++1z when writing C++1z-only code?
try_emplace() does not move from rvalue arguments if the insertion does not happen. This is useful when manipulating maps whose values are move-only types, such as std::unique_ptr .
The map::emplace() is a built-in function in C++ STL which inserts the key and its element in the map container. It effectively increases the container size by one.
If you mean std::map , it stores pairs of values. In each pair, the first value is called the key, and can be used to quickly look up the associated other value.
try_emplace
can indeed replace most uses of emplace
, but if you have an unusual use case of a map
with a non-copyable and immovable key type, try_emplace
will not work because it copies or moves the key. In that case, you must use emplace
with std::pair
's piecewise construction constructor to avoid copies and moves.
Even if your key type is copyable and/or moveable, piecewise construction is the only way to avoid copy or move constructing the key, so there might be cases when you prefer that over try_emplace
.
try_emplace
also doesn't support heterogenous lookup - it can't, because it takes the key.
Suppose we have a std::map<std::string, int, std::less<>> counts;
and a std::string_view
sv
. I want to do the equivalent of ++counts[std::string(sv)];
, but I don't want to create a temporary std::string
, which is just wasteful, especially if the string is already present in the map. try_emplace
can't help you there. Instead you'd do something like
if(auto lb = counts.lower_bound(sv); lb != counts.end() && lb->first == sv) { ++lb->second; } else { counts.emplace_hint(lb, sv, 1); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With