Search code examples
c++dictionarystlemplace

C++ map and unordered_map: emplace to do an upsert/update/replace (for case where value type has no default-constructor)?


This must be a duplicate... if so, help me find, else... help.

I am trying to update an entry in a map, where the mapped-type has no default constructor (and possibly no copy constructor).

Usually we would do something like this:

std::map<K, V> myMap;
myMap[k] = V(...);

However, for the case that we don't have a default c'tor for type V, we may prefer :

std::map<K, V> myMap;
myMap.emplace(k, arg_for_v);

Unfortunately, if we want to replace the entry for k, we cannot use the first syntax (operator[]) because that would require a default construction of V.

Is this the best attempt?:

std::map<K, V> myMap;
myMap.erase(k);
myMap.emplace(k, arg_for_v);

Solution

  • When you can use C++17, there is also `std::map<K, V>::insert_or_assign, which you can use as follows.

    std::map<K, V> myMap;
    
    myMap.insert_or_assign(myKey, myMappedTypeInstance);
    

    The second argument is perfectly forwarded, so in order to avoid copies, you might want

    myMap.insert_or_assign(myKey, std::move(myMappedTypeInstance));
    

    You can also use the return value to check if an insertion or an assignment took place.