pythonc++dictionarystlsetdefault

C++ (STL map) equivalent method to Python's setdefault


So most likely this question had been asked already. Couldn't find it.

Every time I define a std::map and want to insert some value to it, I use this piece of code:

using IntVector = vector < int > ;
map<int, IntVector> mapTmp;

int iKey = 7;
int iVal = 9;
if (mapTmp.find(iKey) == mapTmp.end())
    mapTmp.insert(pair<int, IntVector>(iKey, IntVector()));
mapTmp[iKey].push_back(iKey);

What annoys me is the 3 lines:

if (mapTmp.find(iKey) == mapTmp.end())
    mapTmp.insert(pair<int, IntVector>(iKey, IntVector()));
mapTmp[iKey].push_back(iVal);

Python offer a very useful dict function called: setdefault, that essentially combine those 3 lines into one beautiful line. Say I want to write it in C++, it would be:

mapTmp.setdefault(iKey, IntVector()).push_back(iVal);

Questions

  1. Does C++ offer such functionality?
  2. If not, does everyone write those 3 lines all the time?

Solution

  • The map defined by the C++ standard library has the somewhat counter-intuitive behaviour that merely calling operator[] can mutate the array. In other words, your "if not in map then insert a default" logic is entirely superfluous - the following two segments are equivalent:

    if (mapTmp.find(iKey) == mapTmp.end())
        mapTmp.insert(pair<int, IntVector>(iKey, IntVector()));
    mapTmp[iKey].push_back(iVal);
    

    and:

    mapTmp[iKey].push_back(iVal);
    

    In the second case, if iKey does not exist in the map, it is first default-initialized. For a vector, that's the same as inserting an empty vector.

    For the general case that Python's setdefault covers, I don't know of anything. You might be able to get the effect by providing a custom allocator for the map, but I don't think I'd recommend it.