std::sort降序需显式传入比较器:内置类型用std::greater<T>(),自定义类型推荐lambda;注意头文件、类型匹配、迭代器范围、稳定性及移动语义影响。

用 std::sort 配合 std::greater<int>()</int> 最直接
默认的 std::sort 是升序,要降序就得显式传入比较器。对内置类型(如 int、double)最省事的方式是用 std::greater<t>()</t>,它本质是重载了 operator() 的函数对象,返回 a > b。
实操建议:
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 头文件别漏掉:
#include <algorithm>和#include <functional>(std::greater在后者里) - 类型必须匹配:如果
vector是vector<double>,就得用std::greater<double>(),不能只写std::greater()(C++17 起支持类模板参数推导,但显式写更稳) - 示例:
vector<int> v = {3, 1, 4, 1, 5}; sort(v.begin(), v.end(), greater<int>()); // 结果:{5, 4, 3, 1, 1}
自定义 lambda 表达式更灵活,尤其适用于结构体或复杂逻辑
当 vector 存的是自定义类型(比如 struct Person),或者你想按多个字段、带条件地排序时,lambda 是首选。它能直接捕获外部变量,也避免为简单逻辑单独写函数。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 注意捕获方式:一般用空捕获符
[ ]或[=]就够了,别意外引入悬垂引用 - 参数类型要和 vector 元素一致:比如
vector<string>就写(const string& a, const string& b),避免值拷贝开销 - 示例(按字符串长度降序):
vector<string> words = {"hi", "hello", "a"}; sort(words.begin(), words.end(), [](const string& a, const string& b) { return a.length() > b.length(); }); // 结果:{"hello", "hi", "a"}
别踩 std::sort 的常见坑:迭代器范围、稳定性、移动语义
std::sort 不稳定(相等元素相对顺序可能变),且要求随机访问迭代器——vector 满足,但 list 就得用 list::sort。
容易出错的地方:
- 传错迭代器:写成
sort(v.begin(), v.size())编译不过;正确是v.begin()和v.end() - 对空 vector 或单元素 vector 调用没问题,
std::sort内部有处理,不用额外判断 - 如果 vector 元素类型重载了移动构造/赋值,
std::sort可能触发移动而非拷贝,这通常更快,但要注意移动后原对象处于有效但未指定状态(比如string移动后可能为空)
需要稳定降序?用 std::stable_sort 替换
如果排序前后相等元素的原始位置必须保持(比如先按分数降序,再按提交时间升序的二级排序中,分数相同时不能打乱时间顺序),就得换 std::stable_sort。
它接口和 std::sort 完全一样,只是保证稳定性,代价是常数因子略大、内存占用稍高(通常多一个 O(n) 临时缓冲区)。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 头文件一样,不用额外包含
- 性能敏感场景(比如百万级
int排序)可先 benchmark,多数情况下差异不明显 - 示例:
stable_sort(v.begin(), v.end(), greater<int>());

















