multimap的设计目的是支持重复key,内部基于红黑树实现但不强制key唯一,无operator[]和at(),必须用equal_range()等范围查找获取某key全部value。

multimap 的设计目的就是允许重复 key
和 map 不同,multimap 从标准定义上就支持多个相同 key 的键值对共存。它内部仍基于红黑树实现,但不强制 key 唯一 —— 插入时不会因 key 已存在而拒绝,也不会覆盖旧值。
常见误判是把它当“带重复的 map”,结果发现 operator[] 在 multimap 中根本不存在:这是关键信号,说明它不提供单 key 单值访问语义。
-
multimap没有operator[],也不能用at() - 必须用
insert()插入,用equal_range()、find()或迭代器遍历取值 - 插入相同 key 的多个元素后,它们在容器中按插入顺序(或等价 key 下的内部顺序)连续排列
如何安全获取某个 key 对应的所有 value
不能靠 operator[] 或 at(),得用范围查找。最常用的是 equal_range(),它返回一对迭代器:pair,左闭右开地圈出所有匹配 key 的节点。
multimapmm; mm.insert({1, "a"}); mm.insert({1, "b"}); mm.insert({2, "c"}); auto range = mm.equal_range(1); for (auto it = range.first; it != range.second; ++it) { cout << it->second << endl; // 输出 "a" 和 "b" }
-
find()只返回第一个匹配项,容易漏数据;count()只返回数量,不提供访问路径 -
equal_range()是唯一同时兼顾“存在性判断 + 全量遍历”的标准方法 - 如果 key 不存在,
range.first == range.second,可直接用于空范围判断
insert() 的三种常用写法及行为差异
multimap::insert() 有多个重载,不同写法影响可读性与性能:
立即学习“C++免费学习笔记(深入)”;
-
mm.insert({k, v}):最简洁,调用移动构造,推荐日常使用 -
mm.insert(make_pair(k, v)):C++11 起可用,但注意make_pair类型推导可能出错(比如传入字面量 0 导致 int→long 误转) -
mm.insert(mm.end(), {k, v}):提示插入位置为尾部,但multimap不保证有序插入优化,实际无性能增益,反而降低可读性
所有插入方式都不检查 key 冲突,也不排序 value —— key 决定位置,value 完全由插入顺序决定。
erase() 删除时务必区分“删一个”还是“删全部”
multimap::erase() 有三个重载,行为完全不同:
-
erase(iterator):删单个元素(传入的迭代器指向的那个) -
erase(key_type):删掉该 key 的所有元素,返回删除个数 -
erase(iterator, iterator):删区间,常配合equal_range()使用,例如mm.erase(mm.equal_range(k).first, mm.equal_range(k).second)
最容易踩的坑是误用 erase(key) 后还接着用已失效的迭代器;或者想删一个却写了 erase(key),结果全删了。如果只删第一个匹配项,必须先 find() 再 erase(iterator)。
真正麻烦的地方不在语法,而在逻辑:你得始终明确自己是在处理“一组值”而非“一个值”。哪怕 key 看起来唯一,只要用了 multimap,就要按多值场景去设计查找、遍历和删除流程。











