C++中STL map的setdefault方法等价于Python的方法是什么?

4

很可能这个问题已经被问过了,但我找不到它。

每次我定义一个std::map并想插入一些值时,我使用这段代码:

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);

让我感到烦恼的是这三行代码:

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

Python提供了一个非常有用的dict函数,叫做:setdefault,它可以将那三行代码优雅地合并为一行。如果我想在C++中写出它的话,应该是这样的:

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

问题

  1. C++是否提供此功能?
  2. 如果不是,每个人都要一直写那三行吗?

1
对于前两行代码,!mapTmp.count(iKey) 可以替换 mapTmp.find(iKey) == mapTmp.end(),而 {iKey, {}} 可以替换 pair<int, IntVector>(iKey, IntVector())。在这种情况下,它们是合适的替代方案。 - chris
如果您希望绝对清楚它是一对而不是其他两个成员聚合体,则还有 make_pair(iKey,IntVector()) - celticminstrel
1个回答

6

C++标准库定义的Map有一些反直觉的行为,即仅调用operator[]就可以改变数组。换句话说,您的“如果不在map中,则插入默认值”的逻辑完全是多余的——以下两个代码段是等效的:

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

并且:

mapTmp[iKey].push_back(iVal);

在第二种情况下,如果映射中不存在 iKey,则首先进行默认初始化。对于向量,这与插入空向量相同。
对于 Python 的 setdefault 覆盖的一般情况,我不知道任何方法。您可能可以通过为映射提供自定义分配器来实现效果,但我认为我不建议这样做。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接