std::is_sorted 是最快最安全的标准库解决方案,支持任意迭代器范围、自动处理空/单元素情况、可传自定义谓词(推荐 lambda),对随机访问迭代器有优化,且具备早停特性。

用 std::is_sorted 最快最安全
标准库直接提供解决方案,不用手写循环。它在 <algorithm> 中,支持任意迭代器范围,内部做了优化(比如对小范围可能用展开比较),且对空数组或单元素数组返回 true —— 这符合数学定义,也是多数场景的预期。
常见错误是传错迭代器边界,比如把 end() 写成 begin() + size 却没考虑越界;或者对 std::vector 用了 data() 但忘了加长度,导致迭代器失效。
- 对
std::vector<int> v:用std::is_sorted(v.begin(), v.end()) - 对 C 风格数组
int arr[10]:用std::is_sorted(arr, arr + 10) - 检查降序:传入
std::greater<int>{}作为第三个参数,如std::is_sorted(v.begin(), v.end(), std::greater<int>{})
手写遍历时为什么容易漏掉边界
手动写 for 循环判断升序,典型写法是 for (int i = 1; i < n; ++i) if (a[i] < a[i-1]) return false;。问题在于:如果 n == 0 或 n == 1,循环不执行,逻辑上正确,但很多人会下意识加 if (n <= 1) return true; —— 这反而暴露了对空/单元素情况理解不牢,还可能引入重复判断。
更隐蔽的坑是使用无符号类型做索引,比如 size_t i = 1,当数组为空时 i < 0 永远为假(因为 size_t 是无符号),循环跳过,看似正常,但一旦逻辑扩展(比如想打印第一个违规位置),i-1 就会回绕成极大值。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 永远优先用有符号整型做循环变量,除非明确需要大索引
- 不要单独处理
n == 0或n == 1,让循环条件自然覆盖 - 若必须手写,用迭代器风格:
auto it = begin + 1; while (it != end) { if (*it < *(it - 1)) return false; ++it; },避免索引运算
自定义比较逻辑时传函数对象别传裸函数指针
当你需要按绝对值、字符串长度或结构体字段排序时,得传自定义谓词。传 [](int a, int b) { return abs(a) < abs(b); } 没问题,但若写成 my_cmp(一个普通函数名),编译器可能因模板推导失败报错,尤其在较老的 GCC 或 MSVC 上。
根本原因是 std::is_sorted 的谓词参数是模板类型,裸函数名不是可推导的“类型”,而 lambda 或 std::function 是。此外,捕获变量的 lambda 不能转成函数指针,所以别尝试强制转换。
- 始终用 lambda 表达式,哪怕只有一行:
std::is_sorted(v.begin(), v.end(), [](const auto& x, const auto& y) { return x.id < y.id; }) - 避免
std::function<bool(int,int)>包装,它有调用开销,且没必要 - 如果谓词复杂且复用多,定义为
struct MyCmp { bool operator()(const T& a, const T& b) const { ... } };,然后传MyCmp{}
性能敏感场景要注意迭代器类型
std::is_sorted 对随机访问迭代器(如 vector、数组)能做少量优化,比如跳过中间元素快速采样;但对双向或前向迭代器(如 std::list、std::forward_list),只能顺序扫一遍,时间固定为 O(n)。这时候没有捷径 —— 你无法靠“抽样”可靠判断整个链表是否有序。
另一个现实问题是:如果数组很大且大概率无序(比如刚随机打乱),早停比全扫更重要。而 std::is_sorted 正是这样做的:一发现逆序就立即返回 false,不会继续遍历。这点比自己写的循环更可靠,因为有人会误写成先收集所有逆序位置再判断。
- 对
std::list,别幻想用std::is_sorted“碰运气”,它仍要遍历到第一个错误点 - 如果数据来自外部且不可信,早停特性本身就是关键优势,无需额外优化
- 注意调试构建下某些 STL 实现会插入迭代器有效性检查,略微拖慢,但发布版无影响
真正容易被忽略的是:排序判定依赖于你使用的比较操作是否满足严格弱序。如果自定义谓词里用了 <= 而不是 <,或者对浮点数直接用 == 判断相等,std::is_sorted 的行为就未定义 —— 它可能返回错的结果,也可能崩溃。这点不报编译错误,运行时才出问题。

















