std::ranges::is_sorted默认检查严格升序,要求相邻元素满足a < b,空或单元素容器返回true;支持random_access_range类型,需包含<algorithm>并用std::ranges::前缀;非降序需传std::less_equal<>或lambda。

std::ranges::is_sorted的基本用法
直接传入迭代器范围或容器就能判断是否升序排列,它默认用operator<比较元素。比如std::vector<int>按从小到大排好,std::ranges::is_sorted(v)返回true;只要有一对相邻元素不满足a < b,就立刻返回false。
注意:它只检查“严格升序”,不是“非降序”。{1, 2, 2, 3}会被判为false,因为2 < 2不成立。
- 支持所有满足
random_access_range的类型(如std::vector、std::array、原生数组) - 不修改原数据,只读访问
- 底层是线性扫描,时间复杂度
O(n),没有提前终止优化(实际会提前退出,但标准不保证)
怎么判断非降序(允许相等)
用自定义比较函数,把std::less<>换成std::less_equal<>,或者直接写[](auto a, auto b) { return a <= b; }:
std::vector<int> v = {1, 2, 2, 3};
bool sorted = std::ranges::is_sorted(v, std::less_equal<>{}); // true
别用std::greater<>去反向判断——那是降序,不是“非升序”。如果想检查是否从大到小排列,才用std::greater<>。
立即学习“C++免费学习笔记(深入)”;
-
std::less_equal<>和std::greater_equal<>在C++20中可用,无需手动写lambda - 若用lambda,捕获列表必须为空(不能有
[&]或[x]),否则编译失败 - 比较函数签名必须是
bool(decltype(*it), decltype(*it)),参数类型要能自动推导
常见编译错误和坑
最常遇到的是忘记引入头文件或命名空间:
- 必须包含
<algorithm>,不是<range>或<iterator> - 必须写
std::ranges::is_sorted,写成std::is_sorted调用的是旧版迭代器版本,参数类型不匹配会报错,例如error: no matching function for call to 'is_sorted' - 传
std::list会失败——它不满足random_access_range,编译时报static_assert失败,提示类似'std::list' does not satisfy 'random_access_range' - 空容器或单元素容器总是返回
true,这是标准定义,不是bug
和传统std::is_sorted的区别
新版std::ranges::is_sorted接受容器本身(如v),老版std::is_sorted必须传两个迭代器(如v.begin(), v.end())。混用容易出错:
// ✅ 正确:ranges版本 std::ranges::is_sorted(v); // ❌ 错误:传迭代器给ranges版本(可能编译不过或行为异常) std::ranges::is_sorted(v.begin(), v.end()); // 参数数量不匹配 // ⚠️ 可行但不推荐:老版写法仍可用,但失去范围语义 std::is_sorted(v.begin(), v.end());
如果你的项目已启用C++20且用范围操作较多,优先用std::ranges::is_sorted;但要注意它不支持std::list这类非随机访问容器,而老版std::is_sorted可以——这点容易被忽略,尤其在模板泛型代码里。


















