在 C++20 之后,标准库引入了 ranges 子系统,它提供了一套基于管道式语法的算法和适配器,极大地简化了集合操作的代码。本文以一段常见的数据处理任务为例,演示如何使用 ranges 来实现更加简洁、可读性更强的代码。
1. 背景与目标
假设我们有一份销售数据,每条记录包含商品编号、销量和价格。我们需要:
- 过滤掉销量低于 50 的商品;
- 计算剩余商品的总收入(销量 × 价格);
- 按降序输出收入最高的前 5 条记录。
传统方式需要使用 std::copy_if、std::transform、std::accumulate 等组合,代码量较大;而 ranges 可以一次性完成所有步骤。
2. 示例数据结构
#include <vector>
#include <string>
struct Sale {
std::string sku;
int quantity;
double price;
};
我们假设 `std::vector
sales` 已经填充好了。 — ### 3. 使用 `ranges` 的实现 “`cpp #include #include #include #include #include namespace rv = std::ranges; namespace vw = std::views; int main() { std::vector sales = /* … 填充数据 … */; // 1. 过滤销量 >= 50 的记录 auto filtered = sales | vw::filter([](auto const& s){ return s.quantity >= 50; }); // 2. 计算每条记录的收入 auto revenue = filtered | vw::transform([](auto const& s){ return s.quantity * s.price; }); // 3. 计算总收入 double total_revenue = rv::accumulate(revenue, 0.0); // 4. 取前 5 条收入最高的记录(按降序) auto top5 = filtered | vw::transform([](auto const& s){ return std::make_pair(s, s.quantity * s.price); }) | vw::partial_sort(vw::begin, vw::end, 5, [](auto const& a, auto const& b){ return a.second > b.second; }); // 输出结果 std::cout << std::fixed << std::setprecision(2); std::cout << "总收入: $" << total_revenue << "\n"; std::cout << "前 5 高收入记录:\n"; for (auto const& [s, rev] : top5) { std::cout << s.sku << " | 销量: " << s.quantity << " | 价格: $" << s.price << " | 收入: $" << rev < 以上数据基于 x86_64 + GCC 12.1,编译选项 `-O3 -march=native`。 — ### 5. 结语 C++20 的 `ranges` 子系统提供了一种优雅、类型安全且高效的集合处理方式。熟练掌握其视图与适配器,能够让你在保持性能的同时,大幅提升代码可读性与维护性。下次再面对数据过滤、映射、聚合等任务时,不妨尝试用 `ranges` 写一遍,感受一下它带来的 “一眼看懂” 体验。