std::sort降序需传lambda比较器,如[](const auto& a, const auto& b) { return a > b; },须满足严格弱序,避免浮点nan、相等时返回true等错误。

std::sort 降序要传什么比较器
默认升序,降序得自己给第三个参数——一个能返回 bool 的可调用对象。不是写个函数名就行,得让它能接收两个 const T& 并比较大小。
- 最常用的是 lambda:
[&](const auto& a, const auto& b) { return a > b; } - 如果类型明确(比如
vector<int></int>),直接写[](int a, int b) { return a > b; }更清晰 - 不能只写
a > b(语法错),也不能漏掉return(C++11 起 lambda 单表达式可隐式返回,但显式写更稳) - 别用
std::greater<int>()</int>这种——它确实能降序,但它是函数对象,不是 lambda,不符合你问的“lambda 写法”场景
lambda 捕获列表写空括号还是 &?
绝大多数情况写 [] 就够了。捕获 & 只有在 lambda 里要改外部变量、或调用非静态成员函数时才需要,std::sort 的比较器纯看参数值,不碰外层状态。
- 写
[&]不报错,但多余;万一误用外部变量,排序行为可能意外依赖于未初始化的值 - 如果容器元素是自定义类,且比较逻辑要用到其成员函数(比如
a.name() ),仍不需要捕获——这些函数是 const 成员,直接调用即可 - Clang/GCC 在 -Wall 下会对冗余捕获发警告,
[]是最干净的选择
用 lambda 降序时容易崩的几种情况
崩溃往往不是因为 lambda 写错了,而是比较逻辑违反了严格弱序(strict weak ordering)要求——这是 std::sort 的底层前提。
- 返回
true当且仅当第一个参数“严格小于”第二个:不能写成a >= b(相等时也返回 true,破坏可传递性) - 避免浮点数直接用
>比较(NaN 会导致未定义行为),该用std::greater<double>{}</double>或手动处理 NaN - 如果自定义类重载了
operator>,lambda 里别混用>和(比如 <code>a > bvsb ),确保语义一致 - 对
vector<string></string>降序,别写[](string a, string b) { return a > b; }——按值传参会触发多余拷贝;写const string& a, const string& b
和 std::greater 对比有啥实际差别
功能上没差别,都是降序;但 lambda 更灵活,也更容易出错。
立即学习“C++免费学习笔记(深入)”;
-
std::sort(v.begin(), v.end(), std::greater<int>{})</int>是零开销抽象,编译期确定,无捕获、无状态,最稳 - lambda 在需要动态逻辑时才有优势,比如按结构体某个字段降序:
[](const Person& a, const Person& b) { return a.age > b.age; } - 调试时 lambda 名字是匿名的,gdb 里看不到具体逻辑;
std::greater则明确标识了意图 - 某些旧编译器(如 VS2013 前)对 lambda 支持不全,这时
std::greater是更兼容的选择
真正要注意的从来不是“怎么写 lambda”,而是“这个比较逻辑是否在所有输入下都满足严格弱序”。哪怕一行代码写对了,只要比较函数在某组输入里返回矛盾结果,std::sort 就可能越界访问或死循环。








