std::binary_search要求容器已升序排序,否则结果未定义;参数为迭代器范围[first, last),仅返回bool,不提供位置信息,自定义类型或排序规则需保持比较函数一致。

binary_search 要求容器必须已排序
直接调用 std::binary_search 前,必须确保数据是升序排列的;否则结果未定义——它不会报错,但返回值可能完全错误。常见误用是拿 std::vector 插入一堆数后立刻查,忘了排序。
实操建议:
- 排序用
std::sort(v.begin(), v.end()),别漏掉v.end() - 若数据动态增删频繁,考虑改用
std::set或std::map,它们天然有序且支持find() - 自定义类型需提供严格弱序比较(如重载
operator<或传入比较函数)
函数签名和参数顺序容易写反
std::binary_search 的前两个参数是迭代器范围:[first, last),不是“数组+长度”,也不是“首地址+末地址”。last 是**不包含**的尾后迭代器,这点和几乎所有 STL 算法一致,但新手常在这里越界或漏一个元素。
示例(正确):
立即学习“C++免费学习笔记(深入)”;
std::vector<int> v = {1, 3, 5, 7, 9};
bool found = std::binary_search(v.begin(), v.end(), 5); // true
错误写法(会导致未定义行为):
-
std::binary_search(v.data(), v.data() + v.size(), 5)—— 虽然有时碰巧对,但v.data()不保证是合法迭代器起点(对空 vector 会崩) -
std::binary_search(v.begin(), v.begin() + v.size() - 1, 5)—— 漏掉最后一个元素
它只返回 bool,不告诉你位置
std::binary_search 只回答“有没有”,不返回下标或迭代器。如果后续需要取值、修改或定位,得换用 std::lower_bound 或 std::upper_bound。
对比场景:
- 只需判断存在性(如权限校验、黑名单检查)→ 用
binary_search - 要取第一个 ≥ target 的位置 → 用
lower_bound,再检查是否等于 target - 要插入新元素并保持有序 → 直接用
lower_bound返回的迭代器做insert()
性能上三者都是 O(log n),但 binary_search 少一次解引用,理论略快一点点——不过实际差异几乎不可测。
注意默认比较逻辑和自定义比较的一致性
如果你用 std::sort 时传了自定义比较函数(比如降序),那 binary_search 也必须传同样的函数,否则行为错误。编译器不会提醒你“你排序和查找用的规则不一致”。
示例:
std::vector<int> v = {9, 7, 5, 3, 1};
std::sort(v.begin(), v.end(), std::greater<int>()); // 降序
bool found = std::binary_search(v.begin(), v.end(), 5, std::greater<int>()); // ✅ 必须加第三个参数
漏掉 std::greater<int>() 就会按默认升序逻辑查,在降序数组里找无意义结果。
最容易被忽略的是:比较函数的语义必须和排序时**完全一致**,哪怕只是多一个 const、少一个 &,都可能导致二分过程跳过合法区间。


















