c++标准库中只有std::upper_bound,不存在upper_bound_c++;它定义在中,要求容器已排序且使用随机访问迭代器才能实现o(log n)效率。

别用 upper_bound_C++ —— 这根本不是标准 C++ 的函数名,编译器会直接报错。
为什么找不到 upper_bound_C++?
这是个典型命名混淆:C++ 标准库只有 std::upper_bound,没有带下划线和语言后缀的变体。你搜到的“upper_bound_C++”多半是文档误写、博客标题党,或是旧版自定义封装函数(非标准)。
- 标准头文件是
<algorithm></algorithm>,不是<algorithm.h></algorithm.h>或其他拼写 - 必须显式指定命名空间:
std::upper_bound,不能裸写upper_bound(除非有using,但不推荐) - 它只接受**已排序**的范围,否则行为未定义 —— 不会报错,但结果完全不可靠
std::upper_bound 的基本用法和参数陷阱
它返回第一个 > value 的迭代器,不是下标,也不是布尔值。常见误用是当成“是否存在”的判断函数。
- 签名是
std::upper_bound(first, last, value),其中first和last是左闭右开区间(last不参与比较) - 第三个参数类型必须和容器元素可比较;若用自定义类型,需提供
operator 或传入比较函数 - 对
std::vector<int></int>操作时,别直接传数组名 —— 数组名退化为指针,std::upper_bound(arr, arr + n, x)才对 - 返回值要判是否等于
last,否则解引用可能越界:if (it != vec.end()) { use *it; }
std::vector<int> v = {1, 2, 2, 3, 4, 4, 4, 5};
auto it = std::upper_bound(v.begin(), v.end(), 4); // 指向末尾的 5
// it - v.begin() == 7,不是“4 的个数”和 std::lower_bound 配合查范围时的坑
想查某个值出现的全部位置?得用 lower_bound 和 upper_bound 配合,但二者语义不对称:
立即学习“C++免费学习笔记(深入)”;
-
lower_bound返回第一个 ≥ value 的位置 -
upper_bound返回第一个 > value 的位置 - 所以
[lower, upper)正好是所有 == value 的元素区间 —— 注意是左闭右开 - 如果 value 根本不存在,
lower == upper,此时区间为空,但不会崩溃 - 别用
upper_bound - lower_bound > 0判断存在性,直接用lower != upper更准确
性能与容器选择的影响
std::upper_bound 要求随机访问迭代器才能达到 O(log n)。在 std::list 或 std::forward_list 上强行使用,编译可能通过(依赖 ADL 或隐式转换),但实际是线性遍历,失去二分意义。
- 仅对
std::vector、std::deque、原生数组等支持it + n的容器高效 -
std::set/std::map自带upper_bound成员函数(set.upper_bound(x)),它比std::upper_bound(set.begin(), set.end(), x)更快,且不依赖迭代器随机访问能力 - 用
std::sort排过序的vector再查,比反复插入进set再查,在批量查询场景下往往更快 —— 但得自己维护有序性
最常被忽略的一点:它不检查容器是否真有序。调试时发现结果错位,第一反应不该是改算法,而是加一句 std::is_sorted(v.begin(), v.end()) 确认 —— 尤其当数据来自外部输入或中间计算时。










