All of your map functions perform a search, so you always search the map twice regardless of the key being present or not. You can leverage the fact that insert
retrieves whether the insertion took place (key did not exist) or not (key exists) and act accordingly:
std::unordered_map<int,int> mydict;
bool inserted = false;
auto position = mydict.end();
std::tie(position, inserted) = mydict.insert({key, value});
if (inserted) {
pos->second = value;
}
This would be equivalent to mydict[key] = value
, because we are assigning the new value no matter what. For types where default construction is cheap I would go with operator[]
instead, if that's the only thing you need to do with the map.
All insert
, emplace
and operator[]
can perform an additional construction of value_type
in different situations: insert
and emplace
do this before the insertion takes place and operator[]
default constructs the mapped value when key is not present. Thus, they are not ideal for types whose construction/copy/move is expensive (std::thread
, very large std::array
...). In this case, it is more appropriate to use try_emplace
instead (C++17):
std::unordered_map<int, expensive_type> mydict;
bool inserted = false;
auto position = mydict.end();
std::tie(position, inserted) = mydict.try_emplace(key, expensive_constructor_args);
if (!inserted) {
// no expensive_type has been constructed
// pos->second references the existing value
}