ranges::sort
🚀 C++20 核心算法:std::ranges::sort
std::ranges::sort 是 C++20 引入的 Ranges(范围)算法。它不仅仅是语法糖,更通过引入 投影(Projections) 彻底改变了我们处理容器排序的方式。
1. 语法对比:简洁性与安全性
| 特性 | 老版本 std::sort | C++20 std::ranges::sort |
|---|---|---|
| 传参方式 | 必须显式传递迭代器对 begin() 和 end()。 |
直接传递整个容器(Range)。 |
| 代码示例 | std::sort(v.begin(), v.end()); |
std::ranges::sort(v); |
| 主要优点 | 工业标准,兼容性强。 | 更简洁:减少冗长写法。更安全:避免传错不同容器的迭代器。 |
2. 核心神器:投影 (Projections) 🛠️
投影是 ranges 算法最强大的改进。它允许你在比较之前,先对元素进行一次“变换”或“属性提取”。
函数签名简化版:
std::ranges::sort(range, comparator, projection)
实战解析:
ranges::sort(meetings, {}, [](auto& a) { return a[2]; });
{}(Comparator):占位符,表示使用默认比较规则(即std::less{},从小到大)。[](auto& a) { return a[2]; }(Projection):投影函数。- 逻辑:它告诉
sort不要直接比较两个 vector,而是先提取各自下标为2的元素,然后比较这两个提取出来的值。
- 逻辑:它告诉
- 对比优势:老版本需要将“提取”和“比较”逻辑耦合在比较器中,而 Ranges 方案将比较规则(升序)与提取字段(下标 2)解耦,代码更具描述性。
3. 高级用法示例
场景 A:直接使用成员指针排序
对于结构体,甚至不需要写 Lambda 表达式,直接传入成员变量指针即可,极其优雅。
struct Student { string name; int score; };
vector<Student> students;
// 投影:按 score 成员排序
std::ranges::sort(students, {}, &Student::score);
场景 B:自定义比较规则 + 投影
如果你想按分数降序排列:
std::ranges::sort(students, std::ranges::greater{}, &Student::score);
4. 为什么要在算法竞赛/项目中使用?
- 代码密度极高:省去了大量重复的
.begin()和.end()模板代码。 - 性能零损耗:底层依然采用高效的混合排序算法(Introsort),时间复杂度维持在 $O(n \log n)$。
- 逻辑清晰:处理
vector<vector<int>>等复杂嵌套容器时,投影功能让排序的“依据”一目了然。
浙公网安备 33010602011771号