std::ranges::is_sorted默认检查严格升序,要求相邻元素满足a
std::ranges::is_sorted的基本用法
直接传入迭代器范围或容器就能判断是否升序排列,它默认用
operator比较元素。比如<code>std::vector<int></int>按从小到大排好,std::ranges::is_sorted(v)返回true;只要有一对相邻元素不满足a ,就立刻返回<code>false。注意:它只检查“严格升序”,不是“非降序”。
{1, 2, 2, 3}会被判为false,因为2 不成立。
- 支持所有满足
random_access_range的类型(如std::vector、std::array、原生数组)- 不修改原数据,只读访问
- 底层是线性扫描,时间复杂度
O(n),没有提前终止优化(实际会提前退出,但标准不保证)怎么判断非降序(允许相等)
用自定义比较函数,把
std::less换成std::less_equal,或者直接写[](auto a, auto b) { return a :std::vector<int> v = {1, 2, 2, 3}; bool sorted = std::ranges::is_sorted(v, std::less_equal{}); // true </int>别用
std::greater去反向判断——那是降序,不是“非升序”。如果想检查是否从大到小排列,才用std::greater。
std::less_equal和std::greater_equal在C++20中可用,无需手动写lambda- 若用lambda,捕获列表必须为空(不能有
[&]或[x]),否则编译失败- 比较函数签名必须是
bool(decltype(*it), decltype(*it)),参数类型要能自动推导常见编译错误和坑
最常遇到的是忘记引入头文件或命名空间:
- 必须包含
<algorithm></algorithm>,不是<range></range>或<iterator></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可以——这点容易被忽略,尤其在模板泛型代码里。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!












