C++20 Ranges库: 组合式范围操作
请说明C++20 Ranges库的核心概念,包括范围适配器(Range Adaptor,如views::filter/transform/take/drop)、视图(View)的惰性求值特性,以及与标准算法相比的语法优势。
回答
小字辈
Ranges库提供了操作范围的声明式组合API,核心组件:
范围适配器(views):
std::vector v{1, 2, 3, 4, 5, 6};
auto even_squares = v
| std::views::filter([](int x) { return x % 2 == 0; })
| std::views::transform([](int x) { return x * x; });
// even_squares是惰性视图,遍历时才求值
常用views:
views::filter、views::transform、views::take(n)、views::drop(n)views::reverse、views::keys/views::values(map关键字/值)views::join(展平嵌套范围)、views::split、views::commonviews::iota(start, end)(生成递增序列)
惰性求值:适配器不执行计算,只在迭代时才求值,支持无限范围:
for (int x : std::views::iota(1) | std::views::take(10))
std::cout << x; // 打印1到10
vs 传统算法:
// 传统方式:临时容器、长链嵌套
std::vector<int> tmp;
std::copy_if(v.begin(), v.end(), std::back_inserter(tmp), pred);
std::transform(tmp.begin(), tmp.end(), tmp.begin(), f);
// Ranges:一行、无临时分配、惰性
auto result = v | views::filter(pred) | views::transform(f);
注意:视图不拥有数据,需保证原始范围生命周期覆盖视图的使用期。