std::multimap::equal_range返回一对迭代器,first指向首个键匹配元素,second指向匹配区间末尾后一位置(左闭右开);需用for(it=first; it!=second; ++it)安全遍历,不可解引用second或用

std::multimap::equal_range 返回的是什么
它返回一个 std::pair,其中 first 指向第一个键等于给定值的元素,second 指向最后一个键等于该值的**后一个位置**(即左闭右开区间)。这不是“所有匹配元素的容器”,而是一对迭代器——你得自己遍历。
怎么用 equal_range 遍历所有相同键的元素
别直接解引用 second 迭代器;它可能等于 end(),解引用会崩溃。正确做法是用循环从 range.first 走到 range.second:
auto range = mm.equal_range(key);
for (auto it = range.first; it != range.second; ++it) {
std::cout << it->second << "\n"; // 注意:it->first 是 key,it->second 是值
}
-
mm是std::multimap<k v></k>实例 - 如果
key不存在,range.first == range.second,循环不执行,安全 - 不要写
it —— multimap 迭代器只支持 <code>!=,不支持
为什么不用 find + while 循环找下一个相同键
因为 find 只返回第一个匹配项,后续必须手动调用 upper_bound 或反复 ++it 并检查 it->first == key,容易漏掉边界或越界。而 equal_range 是 O(log n) 一次定位,内部已优化,且语义清晰。
-
equal_range在底层通常复用红黑树的查找逻辑,比多次find或手动推进更高效 - 在并发读场景下,
equal_range返回的两个迭代器保证指向同一段连续逻辑区间,手动推进可能因中间插入导致迭代器失效或跳过元素 - 注意:C++20 起
std::multimap仍不支持contains,所以equal_range仍是查“是否存在+取全部”的最小原子操作
常见错误:把 equal_range 当成 vector 或范围 for 直接用
以下写法是错的:
立即学习“C++免费学习笔记(深入)”;
for (auto& p : mm.equal_range(key)) { ... } // 编译失败:pair 不可迭代
也有人误以为 equal_range 返回的是 std::vector<value_type></value_type>,试图用 .size() 或下标访问 —— 它返回的是 std::pair<iterator iterator></iterator>,没有这些成员。
- 别对
equal_range的返回值用auto&然后当成容器遍历 - 别用
std::distance(range.first, range.second)来“预估”数量再分配 vector —— 虽然可行,但多一次遍历,除非你真需要随机访问 - 如果只是计数,直接用
mm.count(key),它内部就调了equal_range,更简洁









