std::sort 降序需显式传 std::greater() 或 lambda 比较器,注意头文件、类型匹配、数组长度计算及后续算法(如 binary_search)必须使用相同比较器。

用 std::sort 配合 std::greater<int>()</int> 最直接
默认的 std::sort 是升序,想降序就得显式传入比较器。对 int 数组最常用的是 std::greater<int>()</int>,它本质是函数对象,调用时等价于 a > b。
注意:必须包含头文件 <algorithm></algorithm> 和 <functional></functional>(后者常被忽略,不加会编译失败)。
int arr[] = {3, 1, 4, 1, 5};
std::sort(arr, arr + 5, std::greater<int>());</int>
- 数组长度必须手动算清楚,
arr + 5不能写成arr + sizeof(arr)(后者在函数参数里会退化为指针,sizeof返回指针大小) -
std::greater<int>()</int>中的int必须和数组元素类型一致,否则编译报错,比如double数组就得写std::greater<double>()</double> - 如果用
std::vector,写法类似:std::sort(v.begin(), v.end(), std::greater<int>())</int>
自定义 lambda 比较器更灵活,尤其适合结构体或复杂条件
当数组元素是结构体、或需要按多个字段降序(比如先按分数降序,分数相同时按姓名升序),lambda 更直观可控。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
struct Student { int score; std::string name; };
Student students[] = {{85, "Alice"}, {92, "Bob"}, {85, "Charlie"}};
std::sort(students, students + 3, [](const Student& a, const Student& b) {
if (a.score != b.score) return a.score > b.score;
return a.name
- lambda 参数务必用
const&,避免拷贝开销;返回true表示a应排在b前面 - 比较逻辑里不要写
a > b直接返回,这只能支持单一字段;多条件要拆开判断 - lambda 不能捕获外部变量(除非明确需要),否则可能引发未定义行为或编译错误
原始 C 风格数组别用 std::begin/std::end
对栈上定义的原始数组(如 int arr[5]),std::begin(arr) 和 std::end(arr) 是合法的,但一旦数组作为函数参数传入,就退化为指针,std::begin 会失效,编译不过。
- 函数内接收数组参数时,老老实实用
arr和arr + len,别图省事套std::begin/end - 如果真想泛化处理,改用
std::array或std::vector,它们自带begin()/end()成员函数 - 误用
std::begin在指针上会导致类似error: no matching function for call to 'begin'的错误
降序排序后二分查找必须用对应版本
排序完若还要查某个值是否存在,不能直接用 std::binary_search 默认版本——它假定升序。降序数组得配 std::greater 或 lambda,否则结果不可靠。
// 降序排完后查 4 是否存在 bool found = std::binary_search(arr, arr + 5, 4, std::greater<int>());</int>
- 所有依赖有序性的算法(
std::lower_bound、std::upper_bound、std::equal_range)都必须传相同的比较器,否则行为未定义 - 漏传比较器不是报错,而是逻辑错误——可能返回错误位置或判定不存在,调试时很难发现
- 如果后续还要插入新元素并保持降序,也得用对应比较器调用
std::lower_bound找插入点
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










