std::sort 默认按升序排序,常用 lambda 自定义比较器实现降序或复杂规则排序。

std::sort 用 lambda 自定义比较器最常用
默认 std::sort 只支持 比较,要按降序、结构体字段、绝对值等排序,必须传自定义比较器。lambda 是最简洁的选择,编译器能内联,性能不输函数指针。
常见写法:
std::vectorv = {3, 1, 4, 1, 5}; std::sort(v.begin(), v.end(), [](int a, int b) { return a > b; }); // 降序
注意点:
- lambda 必须是「严格弱序」:不能写
a ,否则行为未定义 - 捕获列表为空(
[])最安全;若需访问外部变量,用[&]或[=],但避免在排序中修改被引用的容器 - 对
std::vector<:string>按长度排序:[](const auto& a, const auto& b) { return a.size()
结构体排序必须重载 operator
如果结构体没定义 operator,std::sort 直接报错: invalid operands to binary expression ('MyStruct' and 'MyStruct')。
立即学习“C++免费学习笔记(深入)”;
两种可靠做法:
- 在结构体内加
bool operator - 外部传 lambda:
std::sort(v.begin(), v.end(), [](const auto& a, const auto& b) { return a.name
别用 std::function 包裹比较器——它带运行时开销,且容易因类型擦除导致编译失败;也别用普通函数指针,可读性差、难捕获上下文。
稳定排序选 stable_sort,但代价是额外 O(n) 空间
当相等元素的原始相对顺序需要保留(比如先按分数排、再按提交时间排),必须用 std::stable_sort,它保证稳定性,但底层可能用归并而非快排。
性能差异明显:
-
std::sort平均 O(n log n),原地,缓存友好 -
std::stable_sort最坏 O(n log n),但典型实现需 O(n) 额外内存;小数组可能退化为插入排序 - 若数据已基本有序,
stable_sort实际更快;否则优先选sort
用法完全一致:std::stable_sort(v.begin(), v.end(), cmp);
自定义比较器里别做耗时操作或依赖全局状态
比较器会被调用 O(n log n) 次,任何低效操作都会被放大。典型反例:
- 在比较器里调用
std::sqrt、字符串.find()、文件 IO - 用
rand()或std::time(nullptr)做随机比较——破坏严格弱序,导致崩溃或无限循环 - 依赖全局变量且在多线程中被修改(如 static 计数器),引发数据竞争
正确做法:预计算好关键值,存在 vector 中一起排序;或把复杂逻辑抽成独立函数,在排序前批量处理。
真正麻烦的是比较器逻辑随输入动态变化又难以预计算——这时候该考虑换算法,而不是硬塞进 sort。










