std::ranges::is_sorted直接返回bool判断范围是否升序排列,c++20起定义于,支持所有range概念类型及自定义比较函数,空/单元素范围恒为true。

std::ranges::is_sorted 的基本用法
它直接返回 bool,判断给定范围是否按升序(默认)排列,不修改原数据。C++20 起可用,头文件是 <algorithm></algorithm>,注意不是 <ranges></ranges>。
最简用法:
std::vector<int> v = {1, 2, 4, 3};
bool sorted = std::ranges::is_sorted(v); // false
</int>
支持所有符合 std::ranges::range 概念的类型:数组、std::vector、std::list、C 风格数组(需加 std::ranges::subrange 或用 std::views::all)、甚至自定义迭代器范围。
传入自定义比较函数的注意事项
默认用 std::less(即 ),若要降序或自定义逻辑,必须显式传入 <code>comp 参数,且位置固定在第二个(不能省略第一个参数)。
- 降序检查:
std::ranges::is_sorted(v, std::greater{}) - 按绝对值升序:
std::ranges::is_sorted(v, [](int a, int b) { return std::abs(a) - 错误写法(编译失败):
std::ranges::is_sorted(v, {}) → 缺少比较器类型推导上下文
比较函数签名必须是 bool(decltype(*first), decltype(*first)),不支持三路比较()直接传入。
与 std::is_sorted 的关键区别
旧版 std::is_sorted 接收一对迭代器,std::ranges::is_sorted 接收整个 range —— 这带来两个实际影响:
- 无需手动传
v.begin(), v.end(),更简洁,也避免std::array等类型忘记加.begin()的低级错误 - 对
std::initializer_list直接支持:std::ranges::is_sorted({1,2,3})合法;而std::is_sorted({1,2,3}.begin(), ...)不行(临时对象的begin()是右值,不能取地址) - 性能无差异:两者底层都做相同遍历,但 ranges 版本多一次范围概念检查(编译期,无运行时开销)
常见误判场景和调试建议
它只检查“是否已排序”,不关心是否有重复元素(等价元素合法),也不做稳定性验证。容易被忽略的坑:
- 空范围或单元素范围恒为
true:std::ranges::is_sorted(std::vector<int>{})</int>返回true - 浮点数慎用默认比较:NaN 会导致未定义行为,应先过滤或用
std::isfinite预检 - 自定义类型必须确保比较函数满足严格弱序(strict weak ordering),否则结果不可靠 —— 比如用
替代 <code> 就会出错 - 若用
std::views::filter等适配器构造 range,注意其迭代器类别:某些 view 只提供输入迭代器,std::ranges::is_sorted要求至少前向迭代器(ForwardIterator),否则编译失败
真要查哪两个相邻元素破序?它不提供位置信息 —— 得手写循环或用 std::ranges::adjacent_find 配合自定义谓词。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











