What is the easiest way to get Python `defaultdict` behavior in C ++?

In Python, there is a class called defaultdict, which is essentially a dictionary that will build elements on demand in accordance with the function specified by the user during construction.

Is a similar class already existing in C ++ or do I need to create it myself, inheriting from mapand overwriting the method at?

+4
source share
2 answers

There is nothing in the standard library that would do exactly what you want, you must provide such a class yourself.

, (, std::map); , , . , , :

template <class K, class V, class C, class A>
void foo(const std::map<K, V, C, A> &arg)
{
  doSomething(arg.at(K()));
}

struct MyMap : std::map<int, int>
{
  int at(int) { return 7; }
};

int main()
{
  MyMap m;
  foo(m);  //this will call std::map::at, NOT MyMap::at
}

std::map (, , std::unordered_map, , ) . , , , , . :

template <
  class Key,
  class Value,
  class Comparator = typename std::map<Key, Value>::key_compare,
  class Allocator = typename std::map<Key, Value>::allocator_type
>
class DefaultDict : private std::map<Key, Value, Comparator, Allocator>
{
public:
  // Publish the clear() function as is
  using std::map<Key, Value, Comparator, Allocator>::clear;

  // Provide my own at()
  Value& at(const Key &key) {
    return std::map<Key, Value, Comparator, Allocator>::operator[](key); //call the inherited function
  }

  // Etc.
};
+3

, , defaultdict , map.emplace , , ( ):

unordered_map<int, size_t> map = {{1, 1}, {2, 3}};
// later...
for (int i = 1; i < 4; i++) {
    auto emplace_pair = map.emplace(i, 0);
    emplace_pair.first->second += 1;
}
0

All Articles