在Python中,有一个被称为类的类defaultdict,它本质上是一个字典,它将根据用户在构造时指定的函数按需构造元素.
C++中是否已经存在类似的类,或者我是否必须通过继承map和覆盖at方法来自己创建它?
这不是您问题的直接答案,但如果您想要与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;
}
Run Code Online (Sandbox Code Playgroud)
标准库中没有任何东西可以完全满足您的需求,您必须自己提供这样的类。
但是,请注意,从标准库容器(例如)公开继承是一个坏主意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
}
Run Code Online (Sandbox Code Playgroud)
相反,让您的类按值存储 a 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.
};
Run Code Online (Sandbox Code Playgroud)