为什么+ =在没有值的std :: map键上工作?

时间:2016-11-03 03:26:48

标签: c++ c++11 dictionary stl

我正在寻找人们解决问题的方式here

  

给定由开始和结束时间[[s1,e1],[s2,e2],...](si

其中一个解决方案是执行以下操作:

#include <map>
#include <vector>
#include <algorithm>

using std::max;
using std::map;
using std::vector;

struct Interval {
  int start;
  int end;
  Interval() : start(0), end(0) {}
  Interval(int s, int e) : start(s), end(e) {}
};

int minMeetingRooms(vector<Interval>& intervals) {
    map<int, int> changes;
    for (auto i : intervals) {
      changes[i.start] += 1;
      changes[i.end] -= 1;
    }
    int rooms = 0, maxrooms = 0;
    for (auto change : changes)
      maxrooms = max(maxrooms, rooms += change.second);
    return maxrooms;
}

每次新会议开始时计数器递增,每次会议结束时递减计数器,取每次迭代时该计数器的最大值和先前的最大值。

我对此感到好奇的是地图初始化的部分

for (auto i : intervals) {
  changes[i.start] += 1;
  changes[i.end] -= 1;
}

地图中的值从未设置过,但您仍然可以使用+=运算符。我假设这会导致地图在那个地方创建一个0,然后你会增加,但是这个未定义的行为是什么?每种类型都有默认值吗?例如,如果我有<int, string>的地图,它会将其作为默认值?它只是调用默认构造函数吗?

基本上我想知道的是std::map的内部,它允许一个人添加到一个尚不存在的密钥,以及它如何因类型而异。

作为旁注:

如果我试图编写更多惯用代码,我会提出

if (changes.find(i.start) == changes.end()) changes[i.start] = 0
if (changes.find(i.end) == changes.end()) changes[i.end] = 0

但我猜这是一个性能影响还是什么?

1 个答案:

答案 0 :(得分:2)

阅读the docs

  

返回对映射到等效于key的键的值的引用,如果此类键尚不存在则执行插入。

插入只使用键的默认构造函数,int的默认构造函数生成0。

你的&#34;更惯用的&#34;代码恰恰与惯用语相反。当您想要自动生成时使用operator[],当您尝试避免自动生成时,只能使用count / find

如果你来自Python背景,这可能看起来倒退,但它是惯用的C ++。 C ++ std::map的行为更像是Python defaultdict,而不是dict; operator lookup auto-vivifies,避免自动生成需要显式方法调用。