C++如何对自定义类型使用std::sort?(重载

15次阅读

要让std::sort对自定义类型排序,需提供比较逻辑:可重载operator

C++如何对自定义类型使用std::sort?(重载

要让 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   return a.age }

std::vector 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 });
  • 使用普通函数:
    bool cmpByName(const Person& a, const Person& b) {
      return a.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
#include
#include
#include

struct Book {
  std::string title;
  int year;
  Book(std::string t, int y) : title(std::move(t)), year(y) {}
};

bool operator   return a.year }

int main() {
  std::vector 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   });
}

text=ZqhQzanResources