std::upper_bound返回第一个严格大于给定值的元素迭代器;若不存在则返回end(),要求区间升序且比较器一致,不可用于判断元素存在性。

std::upper_bound返回的是什么位置
std::upper_bound 在已排序区间中查找第一个严格大于给定值的元素迭代器。它不找相等的,也不保证能找到——如果所有元素都 ≤ 目标值,它返回 end() 迭代器。
常见误解是把它当“找等于或大于”的工具,结果发现找不到相等元素时也返回了后面的位置,导致逻辑出错。
- 输入必须是升序(默认比较),否则行为未定义
- 返回迭代器指向的元素满足
comp(value, *it) == true(默认即value ) - 若容器为空或所有元素 ≤ value,返回
end(),务必检查是否越界
怎么用在vector、array这些常见容器上
最常用场景:在排好序的 std::vector 里快速定位插入点,避免重复元素出现在相同位置之前(比如实现 multiset 的上界语义)。
示例:
std::vector<int> v = {1, 2, 2, 3, 4, 4, 4, 5};<br>auto it = std::upper_bound(v.begin(), v.end(), 2);<br>// it 指向第 3 个元素(第一个 3),索引为 3</int>
- 传入的迭代器范围必须有效,
v.begin()到v.end()是标准写法 - 不能直接对
std::list用(不支持随机访问,复杂度退化为 O(n),应改用std::lower_bound配合自定义搜索逻辑) - 对
std::array同样适用,但注意模板推导:需显式写arr.begin(), arr.end(),不能只传数组名
自定义比较函数时容易漏掉的关键点
当你用 std::upper_bound 查找结构体、字符串前缀、或降序排列时,必须确保比较函数和排序时用的一致,否则结果不可预测。
错误示范:
// 排序用的是降序<br>std::sort(v.begin(), v.end(), std::greater<int>());<br>// 但 upper_bound 还用默认小于,就错了<br>auto it = std::upper_bound(v.begin(), v.end(), 3); // ❌</int>
- 降序时必须传相同比较器:
std::upper_bound(v.begin(), v.end(), 3, std::greater<int>())</int> - 自定义类型要重载
operator 或提供二元谓词,且谓词签名必须是 <code>bool( const T&, const T& ) - lambda 捕获需谨慎:若捕获局部变量,确保生命周期覆盖整个调用;推荐无捕获 lambda
和lower_bound、equal_range有什么实际区别
三者都用于有序查找,但语义不同:lower_bound 找第一个 ≥,upper_bound 找第一个 >,equal_range 返回两者组成的 pair。
典型用途:
// 查找所有值为 x 的元素区间<br>auto range = std::equal_range(v.begin(), v.end(), x);<br>// range.first == lower_bound<br>// range.second == upper_bound
- 如果只关心是否存在 x,用
lower_bound+ 比较更轻量 - 如果要插入新元素并保证排在所有 x 之后(比如 multiset 插入策略),必须用
upper_bound - 不要用
upper_bound判断“是否存在 x”——它跳过相等项,可能误判
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











