要让std::sort对自定义类型排序,需提供比较逻辑:可重载operator<(最常用),或传入自定义比较函数(lambda、普通函数、仿函数);二者均须满足严格弱序。

要让 std::sort 能对自定义类型排序,关键在于提供比较逻辑——可通过重载 operator<,或传入自定义比较函数(仿函数、lambda 或普通函数)。
重载 operator<(最常用)
这是最简洁的方式,要求自定义类内部或外部定义 operator<,使其返回 bool,表示“是否严格小于”。std::sort 默认调用它。
例如:
struct Person {std::string name;
int age;
Person(const std::string& n, int a) : name(n), age(a) {}
};
// 全局重载(推荐在类定义同名空间内)
bool operator<(const Person& a, const Person& b) {
return a.age < b.age; // 按年龄升序
}
std::vector<Person> v = {{"Alice", 30}, {"Bob", 25}};
std::sort(v.begin(), v.end()); // ✅ 正常工作
传入自定义比较函数(更灵活)
当不想修改类定义,或需多种排序方式(如按姓名、按年龄降序),可额外传入比较器。它必须是可调用对象,接受两个同类型参数,返回 bool。
立即学习“C++免费学习笔记(深入)”;
- 使用 lambda(推荐,简洁直观):
std::sort(v.begin(), v.end(), [](const Person& a, const Person& b) {
return a.name < b.name; // 按姓名升序
}); - 使用普通函数:
bool cmpByName(const Person& a, const Person& b) {
return a.name < b.name;
}
std::sort(v.begin(), v.end(), cmpByName); - 使用函数对象(仿函数):
struct ByAgeDesc {
bool operator()(const Person& a, const Person& b) const {
return a.age > b.age; // 降序
}
};
std::sort(v.begin(), v.end(), ByAgeDesc{});
注意事项
比较逻辑必须满足严格弱序(strict weak ordering):自反性、非对称性、传递性、等价传递性。常见错误包括:
- 用
<=替代<(破坏非对称性) - 比较中依赖未定义行为(如访问空指针、未初始化成员)
- 在 lambda 中捕获局部变量但其生命周期短于 sort 调用(通常无问题,因 lambda 立即执行)
完整可运行示例
结合重载与 lambda,一目了然:
#include <vector>#include <string>
#include <algorithm>
#include <iostream>
struct Book {
std::string title;
int year;
Book(std::string t, int y) : title(std::move(t)), year(y) {}
};
bool operator<(const Book& a, const Book& b) {
return a.year < b.year; // 默认按出版年份升序
}
int main() {
std::vector<Book> books = {{"C++ Primer", 2012}, {"Effective C++", 2005}};
std::sort(books.begin(), books.end()); // 用 operator<
// 按书名排序(不改类)
std::sort(books.begin(), books.end(), [](const Book& x, const Book& y) {
return x.title < y.title;
});
}









