equal_range返回std::pair,first等价lower_bound(key)、second等价upper_bound(key),构成左闭右开区间,精确覆盖所有键等于目标值的元素,是multimap中查找等值范围的唯一正解。

用 equal_range 拿到同一 key 的所有迭代器区间
直接遍历 multimap 会按插入顺序或键序逐个访问所有元素,没法“按 key 分组”。真正靠谱的做法是用 equal_range ——它返回一个 std::pair<iterator iterator></iterator>,左闭右开地圈出所有 key 相等的元素。
注意:不能用 find,因为它只返回第一个匹配项;也不能靠 lower_bound + 手动递增判断 key 是否相等,既啰嗦又容易越界。
-
equal_range是multimap原生支持的 O(log n) 操作,比手动扫描快得多 - 返回的 pair 中,
first等价于lower_bound(key),second等价于upper_bound(key) - 如果 key 不存在,
first == second,此时循环体不会执行,安全
遍历时别误用 value_type 或漏掉解引用
multimap<k v>::iterator</k> 解引用后是 std::pair<const k v></const>,不是 V。常见错误是写成 it->second 却忘了 it 是迭代器变量名,或者误以为 *it 就是 value。
示例(正确写法):
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
std::multimap<int std::string> mm = {{1,"a"},{1,"b"},{2,"c"}};
auto range = mm.equal_range(1);
for (auto it = range.first; it != range.second; ++it) {
std::cout second
<ul>
<li>别写 <code>(*it).second</code> —— 虽然合法但冗余,<code>it->second</code> 更直观</li>
<li>别把 <code>it</code> 声明成 <code>auto&</code>:迭代器本身是轻量值类型,引用无益,还可能引发 lifetime 问题</li>
<li>如果要用范围 for,得先构造临时容器或用 C++20 的 <code>views::take_while</code>,不推荐——不如直接用 <code>equal_range</code> 清晰</li>
</ul>
<h3>遍历中修改 multimap 会导致迭代器失效</h3>
<p>只要在 <code>equal_range</code> 返回的区间内执行 <code>insert</code>、<code>erase</code> 或任何改变结构的操作,当前所有迭代器(包括 <code>range.first</code> 和 <code>range.second</code>)立即失效。这是标准行为,不是 bug。</p>
<ul>
<li>如果要边遍历边删:先收集待删的迭代器(如 <code>std::vector<decltype></decltype></code>),遍历完再批量 <code>erase</code>
</li>
<li>如果要边遍历边插:改用 <code>for</code> 循环配合 <code>lower_bound</code> 重新查起始位置,避免依赖已失效的 <code>range.second</code>
</li>
<li>多线程下更危险:即使只读,其他线程写也会让迭代器失效,必须加锁或用并发安全容器</li>
</ul>
<h3>key 类型不支持 <code> 时 <code>equal_range</code> 会编译失败</code>
</h3>
<p><code>multimap</code> 底层是红黑树,依赖 key 的严格弱序(默认用 <code>std::less<k></k></code>)。如果你用了自定义结构体作 key,却没定义 <code>operator 或没传比较函数,<code>equal_range</code> 无法编译。</code></p>
<p>例如:</p>
<pre class="brush:php;toolbar:false;">struct Point { int x, y; };
std::multimap<point int> mm; // 错误:Point 没有 operator
<ul>
<li>补上 <code>operator,或用 lambda 传入比较器:<code>std::multimap<point int decltype> mm(cmp);</point></code></code>
</li>
<li>若 key 是 <code>std::string_view</code> 或 <code>std::span</code> 等 C++20 类型,确认编译器支持其默认比较(GCC 10+/Clang 11+ 一般没问题)</li>
<li>别试图用 <code>std::unordered_multimap</code> 替代来绕过比较需求——它没有 <code>equal_range</code>,只有 <code>equal_range</code> 的哈希版叫 <code>bucket</code> 相关接口,语义完全不同</li>
</ul>
C++ 标准库里,“找同一个 key 的所有 value”这件事,<code>equal_range</code> 就是唯一正解。其他绕路写法要么效率低,要么边界处理脆弱,要么根本不能保证正确性。重点盯住迭代器有效性、key 比较定义、解引用语法这三点,基本就不会掉坑里。</point>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










