为什么 += 适用于没有值的 std::map 键?

Why does += work on std::map keys that don't have values?

本文关键字:std map 适用于 为什么      更新时间:2023-10-16

我看到人们是如何解决这里提出的问题的:

给定一个由开始时间和结束时间组成的会议时间间隔数组[[s1,e1],[s2,e2],…][c];),找出所需会议室的最小数量。

解决方案之一是这样做:

#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;
}

每次新会议开始时增加计数器,每次会议结束时减少计数器,每次迭代取该计数器的最大值和上一个最大值。


我想知道的是map初始化的部分

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

但我猜这是性能下降还是什么?

阅读文档:

返回一个值的引用,该值映射到与key等价的键,如果该键不存在则执行插入。

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

你的"更习惯"的代码是完全相反的习惯。当你想要自活时使用operator[],当你试图避免自活时使用count/find

如果您有Python背景,这可能看起来有点落后,但这是惯用的c++。c++ std::map的行为更像Python的defaultdict而不是dict;操作符查找自动激活,避免自动激活需要显式调用方法。