multimap是独立容器,不支持operator[](编译报错),必须用insert或emplace插入;find只返回首个匹配项,取全部需equal_range;erase(key)删所有,erase(iterator)仅删一个且易崩溃;自定义比较器须满足严格弱序。

multimap 不是“能存重复 key 的 map”,它是独立容器,接口行为和 map 有本质区别——用错操作符或查找方式,编译失败或逻辑出错几乎是必然的。
为什么 mm[key] = value 会编译报错
因为 multimap 不支持 operator[]。它的设计前提就是“key 不唯一”,所以无法通过下标唯一定位一个 value;C++ 标准直接禁用了这个操作符。
- 错误写法:
mm[42] = "hello"→ 编译错误:error: no match for 'operator[]' - 正确插入只能用
insert()或emplace() -
insert({key, value})最简洁,类型推导安全;emplace(key, value)避免临时对象,对大value类型更优
find() 只返回第一个匹配项,不是全部
find() 在 multimap 中的行为和 map 一样:只找第一个键相等的元素,返回单个迭代器。它根本不管后面还有没有相同 key 的元素。
- 常见误用:
auto it = mm.find(42); cout second;→ 永远只打印第一个值 - 要取全部,必须用
equal_range(),它返回std::pair<iterator iterator></iterator> - 示例:
auto range = mm.equal_range(42); for (auto it = range.first; it != range.second; ++it) { /* 处理 it->second */ } - 若 key 不存在,
range.first == range.second,循环自动跳过,无需额外判空
erase(key) 和 erase(iterator) 完全不是一回事
multimap::erase 有两个重载版本,参数类型不同,语义完全不同:
-
mm.erase(42):删除所有 key 为 42 的元素,返回被删数量(size_t) -
mm.erase(mm.find(42)):只删第一个,且如果 key 不存在,find()返回end(),擦除end()是未定义行为 —— 这是高频崩溃点 - 想删部分?只能先
equal_range(),再遍历区间内迭代器,逐个调用erase(iterator)(注意它返回下一个有效迭代器) - 删除后,其他未被删的迭代器仍然有效 —— 这点和
vector不同,但别依赖,尤其在循环中删时要小心迭代器失效边界
自定义比较函数时,“相等”不等于“==”
multimap 判断两个 key 是否“等价”,依据的是你传入的比较函数 Comp:当 comp(a, b) == false && comp(b, a) == false 时,认为 a 和 b 等价,允许共存。
- 默认用
std::less<key></key>,所以int类型下42和42等价 - 若自定义比较器(比如忽略大小写的字符串比较),必须保证它满足严格弱序,否则红黑树结构可能崩坏
- 别写
return a == b;当比较函数 —— 这不满足严格弱序,会导致insert行为不可预测甚至崩溃
最常被忽略的一点:当你需要“一对多 + 有序 + 范围查询”,multimap 才是正解;如果只是想快速查、不在乎顺序,unordered_multimap 更快;如果连“多值”都不需要,那 map 就够了——选错容器,后面所有操作都在补救。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











