How to Use std::views::chunk in C++
Introduced in C++23, std::views::chunk is a standard
range adaptor that divides an input sequence into non-overlapping,
contiguous sub-ranges of a specified maximum size. This article explains
the mechanics of how std::views::chunk segments consecutive
elements into fixed-size views, demonstrates how to implement it in
modern C++ code, and details how it handles uneven sequences and range
categories.
Understanding
std::views::chunk
std::views::chunk takes two arguments: an input range
and an integer N representing the chunk size. It produces a
range of ranges, where each inner range represents a chunk of up to
N consecutive elements from the source.
Like most range adaptors in the <ranges> header,
std::views::chunk operates lazily. It does not allocate new
containers or copy elements; instead, it generates sub-ranges on demand
as the outer range is iterated.
Basic Syntax and Usage
You can invoke std::views::chunk either as a functional
call or using the pipe operator (|):
#include <iostream>
#include <vector>
#include <ranges>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8};
// Group elements into chunks of 3
for (auto chunk : numbers | std::views::chunk(3)) {
std::cout << "[ ";
for (int n : chunk) {
std::cout << n << " ";
}
std::cout << "]\n";
}
return 0;
}Output:
[ 1 2 3 ]
[ 4 5 6 ]
[ 7 8 ]
Handling Remaining Elements
If the total number of elements in the source range is not evenly
divisible by N, the final chunk simply contains all
remaining elements. It will have a size strictly less than
N, and no padding, exceptions, or undefined behavior occur.
When the source range is empty, the adaptor yields an empty range of
chunks.
How Chunking Works Under the Hood
The underlying type produced by this view is
std::ranges::chunk_view. Its implementation adapts based on
the iterator concepts supported by the source range:
- Forward and Random-Access Ranges: If the underlying
range models at least
std::ranges::forward_range, iterators can be saved and traversed independently. When accessing a chunk, the view calculates the sub-range using iterator arithmetic (such asstd::ranges::next(current, N, end)). If the source range is sized and random-access, the chunks themselves can provide random-access semantics and constant-time size queries. - Input Ranges: If the source range is an input-only
range (such as reading from an input stream), elements cannot be
revisited. In this case,
chunk_viewmanages an internal counter and caches the current position so that advancing through an inner chunk advances the parent input stream sequentially.
Key Considerations
- Chunk Size Validation: The specified chunk size
Nmust be greater than zero. Passing a value less than or equal to zero leads to undefined behavior. - Element Lifetime: Because
std::views::chunkcreates non-owning views over the original data, the underlying container must outlive the view to prevent dangling references. - Composability: As part of the standard ranges
library,
std::views::chunkcan be seamlessly chained with other adaptors, such asstd::views::filter,std::views::transform, orstd::views::reverse.