cmp函数必须是静态或全局函数,不能是非静态成员函数;需满足严格弱序;用于C风格数组时须传入指针范围且签名正确;lambda捕获需避免悬空引用。

cmp函数必须是静态或全局,不能是普通成员函数
类内定义的普通成员函数隐含 this 指针,而 std::sort 要求比较函数可直接调用(无绑定对象),传入两个参数。直接写成非静态成员函数会编译报错:error: reference to non-static member function must be called。
解决方式只有两种:
- 把
cmp声明为static成员函数(可访问类内static成员,但不能访问实例变量) - 定义为全局函数、
lambda(需捕获时注意生命周期)、或functor(重载operator())
lambda作为cmp传给sort要避免悬空引用
如果在函数内用局部变量构造 lambda 并传给 std::sort,比如按某个外部阈值排序,需确保 lambda 不捕获局部地址或引用——否则 sort 执行时可能已析构。
正确写法示例(按绝对值升序):
立即学习“C++免费学习笔记(深入)”;
std::vector<int> arr = {-3, 1, -2, 4};
std::sort(arr.begin(), arr.end(), [](int a, int b) {
return std::abs(a) < std::abs(b);
});
若需捕获变量,务必用值捕获:[threshold](int a, int b) { return a < threshold && b > threshold; },而非 [&threshold]。
cmp函数必须严格弱序,否则sort行为未定义
std::sort 要求比较函数满足:对任意 a、b、c,cmp(a, a) 必须为 false;若 cmp(a, b) 和 cmp(b, c) 为真,则 cmp(a, c) 也必须为真;且 cmp(a, b) 与 cmp(b, a) 不能同时为真。
常见错误写法:
- 用
<=替代<→ 违反“自反性”,cmp(x,x)返回true - 比较浮点数直接用
<而不加 epsilon 容差 → 因精度问题导致弱序失效 - 在比较中调用随机或状态依赖函数(如
time(0))→ 排序结果不可预测甚至崩溃
数组原生指针排序要显式传入长度,且cmp签名不能错
C 风格数组(如 int arr[5])不能直接用 std::sort(arr, cmp)。必须传迭代器范围:std::sort(arr, arr + 5, cmp),其中 arr 是 int*,arr + 5 是尾后指针。
cmp 函数签名必须是 bool(int, int) 或等价形式(如 bool(const int&, const int&))。若误写成 bool(int*) 或带额外参数,编译器会报错不匹配函数模板参数。
例如合法定义:
bool cmp(int a, int b) { return a % 10 < b % 10; } // 按个位数升序
std::sort(arr, arr + n, cmp);
C++ 数组排序的坑不在语法多难,而在 cmp 的生存期、调用契约和指针边界这三处——漏掉任一,轻则结果错乱,重则运行时崩溃。


















