jeudi 4 mars 2021

Force initialization to 0 when inserting into a std::map

I have a std::map<std::string,std::size_t> of keys mapping counters. When I increment a counter, I don't know if it already exists. If yes, it is incremented, if not it is set to 1. This is easy to do:

std::map<std::string,std::size_t> counters;
//...
auto c_it = counters.find(key);
if(c_it == counters.end())
  counters.insert(key,1);
else
  (*c_it)++;

This is a lot of code for a simple thing... I would like to simply do this:

counters[key]++;

But this generates undefined behavior because std::size_t() is called when the counter doesn't exist in the map, and there is no guarantee that std::size_t() initializes to 0.

I see two potential solutions:

  1. Find / create an type similar to std::size_t forcing initialization to 0 when created with default constructor. Is there such a type in std or boost ?
  2. Find / create a dedicated allocator to replace the default std::allocator<std::pair<const Key,T>> given as 4th template argument of std::map. But I have no idea how to do it.

Note: I use C++11 only (I don't want solutions for C++>=14)

Aucun commentaire:

Enregistrer un commentaire