std::ranges::binary_search要求容器预先排序且使用相同比较规则,否则结果未定义;仅支持随机访问范围,调用更简洁,无需手动传迭代器和默认比较器。

std::ranges::binary_search 用前必须确保容器已排序
它不做排序,只做查找——如果传入乱序容器,结果不可预测,且不会报错。常见错误是直接对 std::vector 调用而忘了排序,返回 false 却以为元素不存在,实际只是二分逻辑失效。
- 排序必须在调用前显式完成,比如用
std::ranges::sort(v) - 支持自定义比较器,但排序和查找必须用同一套规则,否则行为未定义
- 仅适用于支持随机访问的范围(
std::vector、std::array、原生数组),不支持std::list或std::forward_list
调用方式比传统 std::binary_search 更简洁
不用传迭代器首尾,直接传整个范围;也不用额外写比较函数对象,除非需要定制语义。默认按 比较,和 <code>std::sort 默认行为一致。
- 基本写法:
std::ranges::binary_search(v, target) - 带比较器:
std::ranges::binary_search(v, target, std::greater{})(此时 v 必须降序排列) - 注意:第三个参数是谓词(predicate),不是二元比较函数;它接收
target和元素,返回true当元素“等价于” target(即 !pred(a,b) && !pred(b,a))
和 std::binary_search 的关键差异点
两者语义相同(只返回是否存在),但接口设计不同,混用容易出错。老接口要求你传 begin/end,新接口接受任意 range,且自动推导迭代器类型。
- 旧写法:
std::binary_search(v.begin(), v.end(), x) - 新写法:
std::ranges::binary_search(v, x)—— 更少噪声,更难漏掉.begin()/.end() - 性能无差别,底层都是 O(log n),但
std::ranges版本对 ADL 友好,能正确处理自定义 range 类型(只要满足random_access_range)
查不到时别误判为“数据结构问题”
返回 false 只说明没找到,不代表容器损坏或算法失效。最容易忽略的是:浮点数、自定义类型、字符串大小写等场景下,“相等”的定义可能和直觉不符。
- 浮点数慎用,默认
比较无法处理 NaN 或精度误差,应配合 <code>std::abs(a - b) 自定义谓词 - 字符串查找注意 locale:默认按字节比较,中文或带重音字符需用
std::locale配合std::collate - 自定义结构体必须提供符合严格弱序的
operator,否则 <code>std::ranges::sort和binary_search行为都不保证
实际用的时候,先想清楚“我是不是真排过序”,再选谓词,最后检查类型是否支持随机访问——这三个点卡住,基本就稳了。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











