views::transform
C++20Apply a function to each element lazily.
Section hub
std::ranges::transform_view is the concrete view type that applies a function to each element on demand.
std::ranges::views::transform is the range adaptor object used in pipelines and direct adaptor calls to produce a transform_view.
template< ranges::input_range V,
std::copy_constructible F >
requires ranges::view<V> &&
std::is_object_v<F> &&
std::regular_invocable<F&, ranges::range_reference_t<V>> &&
/* invoke_result_t<F&, range_reference_t<V>>& is a valid type */
class transform_view
: public ranges::view_interface<transform_view<V, F>>
(since C++20) (until C++23)
template< ranges::input_range V,
std::move_constructible F >
requires ranges::view<V> &&
std::is_object_v<F> &&
std::regular_invocable<F&, ranges::range_reference_t<V>> &&
/* invoke_result_t<F&, range_reference_t<V>>& is a valid type */
class transform_view
: public ranges::view_interface<transform_view<V, F>>
(since C++23)
namespace views {
inline constexpr /*unspecified*/ transform = /*unspecified*/;
}
(since C++20)
template< ranges::viewable_range R, class F >
requires /* see below */
constexpr ranges::view auto transform( R&& r, F&& fun );
(since C++20)
template< class F >
constexpr /*range adaptor closure*/ transform( F&& fun );
(since C++20)
#include <algorithm>
#include <cstdio>
#include <iterator>
#include <ranges>
#include <string>
char rot13a(const char x, const char a)
{
return a + (x - a + 13) % 26;
}
char rot13(const char x)
{
if ('Z' >= x and x >= 'A')
return rot13a(x, 'A');
if ('z' >= x and x >= 'a')
return rot13a(x, 'a');
return x;
}
int main()
{
auto show = [](const unsigned char x) { std::putchar(x); };
std::string in{"cppreference.com\n"};
std::ranges::for_each(in, show);
std::ranges::for_each(in | std::views::transform(rot13), show);
std::string out;
std::ranges::copy(std::views::transform(in, rot13), std::back_inserter(out));
std::ranges::for_each(out, show);
std::ranges::for_each(out | std::views::transform(rot13), show);
}
transform_view is lazy: applying the transformation function happens when elements are accessed through the view, not when the view is created.
The adaptor stores a view of the underlying range and a callable object. A pipeline such as r | std::views::transform(f) is equivalent in intent to constructing a transform_view over views::all(r) with f.
transform_view does not cache transformed values. Accessing the same position multiple times may invoke the transformation callable multiple times.
transform_view models input_range and can model forward_range, bidirectional_range, random_access_range, and common_range when the underlying view supports them.
It can model sized-range behavior (for example, size()) when the underlying range is sized.
It is not a contiguous range because dereferencing produces transformed values through the callable rather than exposing underlying storage directly.
| Area | Key entries |
|---|---|
| View type and adaptor object | std::ranges::transform_view, std::ranges::views::transform |
| Main member surface | transform_view::transform_view, begin, end, size, base |
| Nested iterator/sentinel surface | transform_view::iterator, iterator::operator*, iterator::iter_move, transform_view::sentinel |
| Related entries | deduction guides, range adaptor closure, ranges::transform algorithm |
transform_view changed from requiring a copy-constructible function object to a move-constructible one in C++23. The page includes both declaration forms to show that boundary.
This hub groups the ranges library by user task rather than by raw reference tree shape. View types and adaptor objects are presented as the same conceptual item.
Start here for the adapters most people reach for first when building pipelines.
Apply a function to each element lazily.
Keep only elements that satisfy a predicate.
Keep the first N elements from a source range.
Skip the first N elements and expose the rest.
Split a range into non-overlapping fixed-size subranges.
Flatten a range of ranges into a single lazy sequence.
These adapt shape, ownership, or projection rather than representing the “headline” pipeline steps.
Normalize a range into a view-compatible form.
Adapt iterator/sentinel pairs into a common-range shape.
Wrap an existing range by reference.
Store and expose a range with unique ownership.
Package iterator + sentinel as a view-like object.
Project tuple-like elements to their key component.
Project tuple-like elements to their value component.
Newer adapters, kept as a compact scan list with only standard badges.
A lighter-weight index of the full ranges surface, grouped by conceptual task instead of raw page-tree names.