multimap能存重复键是因为其设计目标即支持键重复,插入时不检查键是否存在,直接按序插入;底层虽为红黑树,但比较规则仅依赖严格弱序,相等键被允许并相邻存储。

multimap为什么能存重复键
因为 multimap 的设计目标就是允许键重复——它不像 map 那样在插入时检查键是否已存在,而是直接追加。底层是红黑树,但比较规则只用 判断顺序,不禁止相等键。所以只要两个键 <code>a 和 <code>b 都为 false(即等价),就能并存。
常见误判:以为 multimap 是“带重复的 map”,其实它是独立容器,接口行为也不同——比如 find() 只返回一个迭代器,而 equal_range() 才是查全部匹配项的正解。
插入重复键的正确写法
直接用 insert(),别用 [] 操作符(multimap 不支持下标赋值,编译报错:error: no match for operator[])。
-
mm.insert({key, value});—— 推荐,简洁且类型推导安全 -
mm.insert(std::make_pair(key, value));—— 兼容老标准,但注意std::pair构造可能隐式转换 -
mm.emplace(key, value);—— 避免临时对象,性能略优,尤其对大 value 类型
错误示例:mm[key] = value; → 编译失败;mm.insert(std::pair<int int>(key, value));</int> → 冗余,且易因类型不匹配导致构造失败。
遍历所有相同键的值
不能靠 find(),它只返回第一个匹配位置;必须用 equal_range() 获取左闭右开区间。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
auto range = mm.equal_range(42);
for (auto it = range.first; it != range.second; ++it) {
std::cout second
<p>注意:<code>equal_range()</code> 返回 <code>std::pair<iterator iterator></iterator></code>,不是单个迭代器;若键不存在,<code>range.first == range.second</code>,循环自动跳过,无需额外判空。</p>
<p>性能提示:在大量重复键场景下,<code>equal_range()</code> 是 O(log n + k),k 是该键出现次数;逐个 <code>find()</code> 再递增找下一个会退化成 O(k log n)。</p>
<h3>删除指定键的所有元素</h3>
<p>用 <code>erase(key)</code> 重载版本,它返回删除个数(<code>size_t</code>),不是迭代器——这点和 <code>map::erase()</code> 不同。</p>
-
mm.erase(42);→ 删除所有键为 42 的节点,返回实际删掉的数量 -
mm.erase(mm.find(42));→ 错!只删第一个,且find()对不存在的键返回end(),擦除end()是未定义行为 - 想删部分?只能手动遍历
equal_range()区间,用erase(iterator)逐个删(注意迭代器失效)
容易忽略:删除后,其他迭代器是否有效?multimap 的 erase 不会使其他迭代器失效(除了被删的那个),但 erase(iterator) 返回的是下一个有效迭代器,而 erase(key) 没有返回迭代器,要继续遍历得重新 equal_range()。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










