在 C++23 中,标准库通过 std::ranges 提供了新的视图适配器 std::views::chunk,它可以将一个序列按照指定的固定大小切分成多个小块,并以视图的形式暴露出来。这种分块操作不会拷贝原数据,只是在遍历时控制每次取出的元素个数,非常适合批处理、分页以及并行计算前的划分。

基本用法
使用 std::views::chunk 时,只需要将一个 range 和块大小作为参数传入即可。返回的对象是一个 range of ranges,外层遍历拿到每一块,内层遍历拿到块里的元素。
#include <iostream>
#include <vector>
#include <ranges>
int main() {
std::vector<int> data = {1, 2, 3, 4, 5, 6, 7};
// 按每块 3 个元素分块
for (auto chunk : data | std::views::chunk(3)) {
for (int x : chunk) {
std::cout << x << ' ';
}
std::cout << 'n';
}
return 0;
}
上面代码会输出三行,分别是 1 2 3、4 5 6 和 7,最后一块不足三个元素时也正常输出。
与手动分块的区别
在 C++23 之前,我们往往用下标循环来手动切分,既容易出错也不够直观。下面的表格列出了两者的主要差异:
| 方式 | 代码复杂度 | 是否产生拷贝 | 可读性 |
|---|---|---|---|
| 手动下标分块 | 较高 | 否 | 一般 |
| std::views::chunk | 低 | 否 | 好 |
注意事项
- 块大小必须为正整数,传入 0 会导致未定义行为。
- 原序列不能是临时对象且被视图引用时要注意生命周期。
- chunk 视图本身是惰性求值的,不会立刻分配内存。
结合其他视图
std::views::chunk 可以和其他适配器组合,比如先过滤再分块:
#include <iostream>
#include <vector>
#include <ranges>
int main() {
std::vector<int> nums = {1, 2, 3, 4, 5, 6, 7, 8};
auto view = nums
| std::views::filter([](int n) { return n % 2 == 0; })
| std::views::chunk(2);
for (auto c : view) {
for (int v : c) std::cout << v << ' ';
std::cout << 'n';
}
return 0;
}
该程序先保留偶数,再两两分块,输出为 2 4 和 6 8。通过组合视图,可以用声明式写法替代繁琐的循环逻辑。
小结
std::views::chunk 是 C++23 中非常实用的范围适配器,能以零拷贝方式将序列按固定大小分块,配合其他视图可写出简洁、易维护的数据处理代码。在需要批量消费元素的场景下,建议优先使用它来代替手写下标切分。
C++23std::views::chunkrange_adaptor修改时间:2026-07-26 12:27:27