Библиотека ranges (начиная с C++20)
Библиотека ranges — это расширение и обобщение библиотек алгоритмов и итераторов, которое делает их более мощными благодаря возможности комбинировать их и меньшей подверженности ошибкам.
Библиотека создаёт и обрабатывает представления диапазонов — лёгкие объекты, которые косвенно представляют итерируемые последовательности (диапазоны). Диапазоны представляют собой абстракцию над
-
[begin,end)– парами итераторов, например диапазонами, полученными посредством неявного преобразования контейнеров. Для всех алгоритмов, принимающих пары итераторов, теперь существуют перегрузки, принимающие диапазоны (например,ranges::sort) - begin
+[0,size)– последовательностями с заданным количеством элементов, например диапазоном, возвращаемымviews::counted -
[begin,предикатом)– последовательностями с условием завершения, например диапазоном, возвращаемымviews::take_while -
[begin,..)– неограниченными последовательностями, например диапазоном, возвращаемымviews::iota
Библиотека ranges включает алгоритмы для диапазонов, которые применяются к диапазонам сразу, и адаптеры диапазонов, которые применяются к представлениям лениво. Адаптеры можно объединять в конвейеры, чтобы их действия выполнялись при обходе представления.
Определено в заголовке <ranges> | ||
|---|---|---|
namespace std {
namespace views = ranges::views;
}
| (начиная с C++20) |
Псевдоним пространства имён std::views предоставлен для краткой записи std::ranges::views.
Определено в пространстве имён std::ranges |
|
|---|---|
Доступ к диапазонам |
|
Определено в заголовке <ranges> |
|
Определено в заголовке <iterator> |
|
|
(C++20) | возвращает итератор на начало диапазона (объект-точка настройки) |
|
(C++20) | возвращает сентинел, обозначающий конец диапазона (объект-точка настройки) |
|
(C++20) | возвращает итератор на начало диапазона только для чтения (объект-точка настройки) |
|
(C++20) | возвращает сентинел, обозначающий конец диапазона только для чтения (объект-точка настройки) |
|
(C++20) | возвращает обратный итератор для диапазона (объект-точка настройки) |
|
(C++20) | возвращает обратный конечный итератор для диапазона (объект-точка настройки) |
|
(C++20) | возвращает обратный итератор для диапазона только для чтения (объект-точка настройки) |
|
(C++20) | возвращает обратный конечный итератор для диапазона только для чтения (объект-точка настройки) |
|
(C++26) | возвращает целое число, равное подсказке о резервировании, заданной диапазоном (объект-точка настройки) |
|
(C++20) | возвращает целое число, равное размеру диапазона (объект-точка настройки) |
|
(C++20) | возвращает целое число со знаком, равное размеру диапазона (объект-точка настройки) |
|
(C++20) | проверяет, пуст ли диапазон (объект-точка настройки) |
|
(C++20) | получает указатель на начало непрерывного диапазона (объект-точка настройки) |
|
(C++20) | получает указатель на начало непрерывного диапазона только для чтения (объект-точка настройки) |
Примитивы диапазонов |
|
Определено в заголовке <ranges> |
|
|
(C++20)(C++23)(C++20)(C++23) | получает типы итератора и сентинела диапазона (шаблон псевдонима) |
|
(C++20)(C++20)(C++20) | получает типы размера, разности и значения диапазона (шаблон псевдонима) |
|
(C++20)(C++23)(C++20)(C++20) | получает ссылочные типы диапазона (шаблон псевдонима) |
Обработка висячих итераторов |
|
Определено в заголовке <ranges> |
|
|
(C++20) | тип-заполнитель, указывающий, что итератор или subrange не следует возвращать, поскольку он станет висячим (класс) |
|
(C++20) | получает тип итератора или тип subrange для borrowed_range(шаблон псевдонима) |
Другие вспомогательные средства |
|
Определено в заголовке <ranges> |
|
|
(C++23) | помечает диапазон, который следует обрабатывать как последовательность, а не как одно значение (шаблон класса) |
Концепции диапазонов |
|
Определено в заголовке <ranges> |
|
|
(C++20) | задаёт требования к типу, являющемуся диапазоном, то есть предоставляющему итератор begin и сентинел end (концепция) |
|
(C++20) | задаёт требования к типу, являющемуся range, итераторы которого, полученные из выражения этого типа, можно безопасно возвращать без риска их превращения в висячие (концепция) |
|
(C++26) | задаёт требования к диапазону, способному оценить свой размер за постоянное время (концепция) |
|
(C++20) | задаёт требования к диапазону, размер которого известен за постоянное время (концепция) |
|
(C++20) | задаёт требования к диапазону-представлению, то есть копирование, перемещение и присваивание которого выполняются за постоянное время (концепция) |
|
(C++20) | задаёт требования к диапазону, тип итератора которого удовлетворяет концепции input_iterator (концепция) |
|
(C++20) | задаёт требования к диапазону, тип итератора которого удовлетворяет концепции output_iterator (концепция) |
|
(C++20) | задаёт требования к диапазону, тип итератора которого удовлетворяет концепции forward_iterator (концепция) |
|
(C++20) | задаёт требования к диапазону, тип итератора которого удовлетворяет концепции bidirectional_iterator (концепция) |
|
(C++20) | задаёт требования к диапазону, тип итератора которого удовлетворяет концепции random_access_iterator (концепция) |
|
(C++20) | задаёт требования к диапазону, тип итератора которого удовлетворяет концепции contiguous_iterator (концепция) |
|
(C++20) | задаёт требования к диапазону, типы итератора и сентинела которого совпадают (концепция) |
|
(C++20) | задаёт требования, которым должен удовлетворять range, чтобы его можно было безопасно преобразовать в view (концепция) |
|
(C++23) | задаёт требования к диапазону с элементами только для чтения (концепция) |
|
(C++26) | задаёт требования к диапазону, размер которого известен за постоянное время и элементы которого доступны произвольно (концепция, используемая только для пояснения*) |
Преобразования диапазонов |
|
Определено в заголовке <ranges> |
|
|
(C++23) | создаёт новый объект, не являющийся представлением, из входного диапазона (шаблон функции) |
Представления |
|
Определено в заголовке <ranges> |
|
|
(C++20) | вспомогательный шаблон класса для определения view с использованием идиомы рекурсивного шаблона (шаблон класса) |
|
(C++20) | объединяет пару «итератор — сентинел» в view (шаблон класса) |
Фабрики диапазонов
Определено в заголовке <ranges> |
|
|---|---|
Определено в пространстве имён std::ranges |
|
|
(C++20) | пустое view без элементов(шаблон класса) (шаблон переменной) |
|
(C++20) | view, содержащий один элемент с заданным значением(шаблон класса) (объект-точка настройки) |
|
(C++20) | view, состоящий из последовательности, полученной многократным увеличением начального значения(шаблон класса) (объект-точка настройки) |
|
(C++26) | view, генерирующий последовательность возрастающих значений от 0 до n(объект-точка настройки) |
|
(C++23) | view, состоящий из последовательности, генерируемой многократным созданием одного и того же значения(шаблон класса) (объект-точка настройки) |
|
(C++20) | view, состоящий из элементов, полученных последовательным применением operator>> к связанному входному потоку(шаблон класса) (объект-точка настройки) |
Адаптеры диапазонов
Определено в заголовочном файле <ranges> |
|
|---|---|
Определено в пространстве имён std::ranges |
|
|
(C++23) | вспомогательный базовый шаблон класса для определения объекта-замыкания адаптера диапазона (шаблон класса) |
|
(C++20) | view, включающее все элементы range(шаблон псевдонима) (объект-адаптер диапазона) |
|
(C++20) | view элементов другого range (шаблон класса) |
|
(C++20) | view, которому принадлежит некоторый range (шаблон класса) |
|
(C++23) | view последовательности, преобразующее каждый элемент в rvalue(шаблон класса) (объект-адаптер диапазона) |
|
(C++20) | view, состоящее из элементов range, удовлетворяющих предикату(шаблон класса) (объект-адаптер диапазона) |
|
(C++20) | view последовательности, применяющее функцию преобразования к каждому элементу(шаблон класса) (объект-адаптер диапазона) |
|
(C++20) | view, состоящее из первых N элементов другого view(шаблон класса) (объект-адаптер диапазона) |
|
(C++20) | view, состоящее из начальных элементов другого view до первого элемента, для которого предикат возвращает false(шаблон класса) (объект-адаптер диапазона) |
|
(C++20) | view, состоящее из элементов другого view без первых N элементов(шаблон класса) (объект-адаптер диапазона) |
|
(C++20) | view, состоящее из элементов другого view без начальной подпоследовательности элементов до первого элемента, для которого предикат возвращает false(шаблон класса) (объект-адаптер диапазона) |
|
(C++20) | view, состоящее из последовательности, полученной путём разворачивания view из ranges(шаблон класса) (объект-адаптер диапазона) |
|
(C++23) | view, состоящее из последовательности, полученной путём разворачивания представления диапазонов с разделителем между элементами(шаблон класса) (объект-адаптер диапазона) |
|
(C++20) | view подпоследовательностей, полученных разбиением другого view с помощью разделителя(шаблон класса) (объект-адаптер диапазона) |
|
(C++20) | view подпоследовательностей, полученных разбиением другого view с помощью разделителя(шаблон класса) (объект-адаптер диапазона) |
|
(C++26) | view, состоящее из конкатенации адаптированных представлений(шаблон класса) (объект точки настройки) |
|
(C++20) | создаёт подпоследовательность из итератора и количества элементов (объект точки настройки) |
|
(C++20) | преобразует view в common_range(шаблон класса) (объект-адаптер диапазона) |
|
(C++20) | view, перебирающее элементы другого двунаправленного представления в обратном порядке(шаблон класса) (объект-адаптер диапазона) |
|
(C++23) | преобразует view в constant_range(шаблон класса) (объект-адаптер диапазона) |
|
(C++20) | принимает view, состоящее из значений tuple-like, и число N и создаёт view из N-го элемента каждого кортежа(шаблон класса) (объект-адаптер диапазона) |
|
(C++20) | принимает view, состоящее из пароподобных значений, и создаёт view из первых элементов каждой пары(шаблон класса) (объект-адаптер диапазона) |
|
(C++20) | принимает view, состоящее из пароподобных значений, и создаёт view из вторых элементов каждой пары(шаблон класса) (объект-адаптер диапазона) |
|
(C++23) | view, сопоставляющее каждому элементу адаптированной последовательности кортеж из позиции элемента и его значения(шаблон класса) (объект-адаптер диапазона) |
|
(C++23) | view, состоящее из кортежей ссылок на соответствующие элементы адаптированных представлений(шаблон класса) (объект точки настройки) |
|
(C++23) | view, состоящее из результатов применения функции преобразования к соответствующим элементам адаптированных представлений(шаблон класса) (объект точки настройки) |
|
(C++23) | view, состоящее из кортежей ссылок на соседние элементы адаптированного представления(шаблон класса) (объект-адаптер диапазона) |
|
(C++23) | view, состоящее из пар ссылок на соседние элементы адаптированного представления(объект точки настройки) |
|
(C++23) | view, состоящее из результатов применения функции преобразования к соседним элементам адаптированного представления(шаблон класса) (объект-адаптер диапазона) |
|
(C++23) | view, состоящее из результатов применения функции преобразования к каждой паре соседних элементов адаптированного представления(объект точки настройки) |
|
(C++23) | диапазон из views, представляющих собой неперекрывающиеся последовательные блоки элементов другого view размером N(шаблон класса) (объект-адаптер диапазона) |
|
(C++23) | view, M-й элемент которого является view над элементами с M-го по (M + N - 1)-й другого view(шаблон класса) (объект-адаптер диапазона) |
|
(C++23) | разбивает view на подпоследовательности между каждой парой соседних элементов, для которых заданный предикат возвращает false(шаблон класса) (объект-адаптер диапазона) |
|
(C++23) | view, состоящее из элементов другого view с переходом через каждые N элементов(шаблон класса) (объект-адаптер диапазона) |
|
(C++23) | view, состоящее из кортежей результатов вычисления n-арного декартова произведения адаптированных представлений(шаблон класса) (объект точки настройки) |
|
(C++26) | view, кэширующее последний элемент базовой последовательности, к которому обращались(шаблон класса) (объект-адаптер диапазона) |
|
(C++26) | преобразует view в диапазон, являющийся только input_range и не являющийся common_range(шаблон класса) (объект-адаптер диапазона) |
Генераторы диапазонов (с C++23)
Определено в заголовочном файле <generator> |
|
|---|---|
Определено в пространстве имён std |
|
|
(C++23) | view, представляющее синхронный генератор сопрограммы (шаблон класса) |
Вспомогательные элементы
Объекты-адаптеры диапазонов
См. RangeAdaptorObject (RAO).
Объекты-замыкания адаптера диапазона
См. RangeAdaptorClosureObject (RACO).
Объекты точек настройки
См. объект точки настройки (CPO).
Оболочка с возможностью присваивания
Некоторые адаптеры диапазонов оборачивают свои элементы или функциональные объекты с помощью copyable-box(до C++23)movable-box(с C++23). Оболочка добавляет обёрнутому объекту возможность присваивания, если это необходимо.
Нераспространяющийся кэш
Некоторые адаптеры диапазонов описываются через шаблон класса non-propagating-cache, предназначенный только для описания и почти аналогичный std::optional<T> (различия см. в описании).
Условный тип const
template< bool Const, class T > using /*maybe-const*/ = std::conditional_t<Const, const T, T>; | (только для описания*) |
Шаблон псевдонима /*maybe-const*/ — это сокращённая запись, используемая для условного добавления квалификатора const к типу T.
Вспомогательные шаблоны типов целочисленного вида
template< /*is-integer-like*/ T > using /*make-signed-like-t*/<T> = /* see description */; | (1) | (только для описания*) |
template< /*is-integer-like*/ T > using /*make-unsigned-like-t*/<T> = /* see description */; | (2) | (только для описания*) |
template< /*is-integer-like*/ T >
/*make-unsigned-like-t*/<T> /*to-unsigned-like*/( T t )
{
return static_cast</*make-unsigned-like-t*/<T>>(t);
}
| (3) | (только для описания*) |
T: - Если
Tявляется целочисленным типом, /*make-signed-like-t*/<T> — это std::make_signed_t<T>. - В противном случае /*make-signed-like-t*/<T> — это соответствующий знаковый тип целочисленного вида с неуказанным именем и той же шириной, что и
T.
T: - Если
Tявляется целочисленным типом, /*make-unsigned-like-t*/<T> — это std::make_unsigned_t<T>. - В противном случае /*make-signed-like-t*/<T> — это соответствующий беззнаковый тип целочисленного вида с неуказанным именем и той же шириной, что и
T.
t в /*make-unsigned-like-t*/<T>.Вспомогательные средства для объектов точек настройки
template< ranges::input_range R >
constexpr auto& /*possibly-const-range*/(R& r) noexcept
{
if constexpr (ranges::input_range<const R>)
return const_cast<const R&>(r);
else
return r;
}
| (1) | (только для описания*) |
template< class T >
constexpr auto /*as-const-pointer*/( const T* p ) noexcept
{
return p;
}
| (2) | (только для описания*) |
Некоторые объекты точек настройки доступа к диапазонам описываются через эти шаблоны функций, предназначенные только для описания.
r с квалификатором const, если constR удовлетворяет требованиям input_range; в противном случае возвращает r без каких-либо преобразований.Вспомогательные средства для адаптеров диапазонов
template< class F, class Tuple >
constexpr auto /*tuple-transform*/( F&& f, Tuple&& tuple )
{
return std::apply([&]<class... Ts>(Ts&&... args)
{
return std::tuple<std::invoke_result_t<F&, Ts>...>
(std::invoke(f, std::forward<Ts>(args))...);
}, std::forward<Tuple>(tuple));
}
| (1) | (только для описания*) |
template< class F, class Tuple >
constexpr void /*tuple-for-each*/( F&& f, Tuple&& tuple )
{
std::apply([&]<class... Ts>(Ts&&... args)
{
(static_cast<void>(std::invoke(f, std::forward<Ts>(args))), ...);
}, std::forward<Tuple>(tuple));
}
| (2) | (только для описания*) |
template< class T >
constexpr T& /*as-lvalue*/( T&& t )
{
return static_cast<T&>(t);
}
| (3) | (только для описания*) |
Некоторые адаптеры диапазонов описываются через эти шаблоны функций, предназначенные только для описания.
f к каждому элементу tuple.f к каждому элементу tuple и ничего не возвращает.t как lvalue.Вспомогательные концепты
Следующие концепты, используемые только для описания, применяются для нескольких типов, но не являются частью интерфейса стандартной библиотеки.
template< class R >
concept /*simple-view*/ =
ranges::view<R> && ranges::range<const R> &&
std::same_as<ranges::iterator_t<R>, ranges::iterator_t<const R>> &&
std::same_as<ranges::sentinel_t<R>, ranges::sentinel_t<const R>>;
| (1) | (только для описания*) |
template< class I >
concept /*has-arrow*/ =
ranges::input_iterator<I> &&
(std::is_pointer_v<I> || requires(const I i) { i.operator->(); });
| (2) | (только для описания*) |
template< class T, class U >
concept /*different-from*/ =
!std::same_as<std::remove_cvref_t<T>, std::remove_cvref_t<U>>;
| (3) | (только для описания*) |
template< class R >
concept /*range-with-movable-references*/ =
ranges::input_range<R> &&
std::move_constructible<ranges::range_reference_t<R>> &&
std::move_constructible<ranges::range_rvalue_reference_t<R>>;
| (4) | (только для описания*) |
template< bool C, class... Views >
concept /*all-random-access*/ =
(ranges::random_access_range
<std::conditional_t<C, const Views, Views>> && ...);
| (5) | (только для описания*) |
template< bool C, class... Views >
concept /*all-bidirectional*/ =
(ranges::bidirectional_range
<std::conditional_t<C, const Views, Views>> && ...);
| (6) | (только для описания*) |
template< bool C, class... Views >
concept /*all-forward*/ =
(ranges::forward_range
<std::conditional_t<C, const Views, Views>> && ...);
| (7) | (только для описания*) |
Примечания
| Макрос проверки поддержки возможности | Значение | Стандарт | Возможность |
|---|---|---|---|
__cpp_lib_generator | 202207L | (C++23) | std::generator – генератор синхронных корутин для диапазонов |
__cpp_lib_ranges | 201911L | (C++20) | Библиотека диапазонов и алгоритмы с ограничениями |
202106L |
(C++23) (DR20) | Представления, не являющиеся инициализируемыми по умолчанию | |
202110L |
(C++23) (DR20) | Представления с владением | |
202202L | (C++23) | ranges::range_adaptor_closure | |
202207L | (C++23) | Ослабление требований к адаптерам диапазонов, позволяющее использовать типы, поддерживающие только перемещение | |
202211L | (C++23) | Удаление «отравляющих перегрузок» (P2602) в ranges::begin и т. д. | |
202302L | (C++23) | Ослабление требований к диапазонам, позволяющее использовать некоторые проекции | |
202406L |
(C++26) (DR20) | Удаление требования к общей ссылке для концептов косвенной вызываемости | |
__cpp_lib_ranges_as_const | 202207L | (C++23) | std::const_iterator, ranges::as_const_view |
__cpp_lib_ranges_as_rvalue | 202207L | (C++23) | ranges::as_rvalue_view |
__cpp_lib_ranges_cache_latest | 202411L | (C++26) | ranges::cache_latest_view |
__cpp_lib_ranges_cartesian_product | 202207L | (C++23) | ranges::cartesian_product_view |
__cpp_lib_ranges_chunk | 202202L | (C++23) | ranges::chunk_view |
__cpp_lib_ranges_chunk_by | 202202L | (C++23) | ranges::chunk_by_view |
__cpp_lib_ranges_concat | 202403L | (C++26) | ranges::concat_view |
__cpp_lib_ranges_enumerate | 202302L | (C++23) | ranges::enumerate_view |
__cpp_lib_ranges_indices | 202506L | (C++26) | ranges::views::indices |
__cpp_lib_ranges_join_with | 202202L | (C++23) | ranges::join_with_view |
__cpp_lib_ranges_repeat | 202207L | (C++23) | ranges::repeat_view |
__cpp_lib_ranges_reserve_hint | 202502L | (C++26) | ranges::reserve_hint и ranges::approximately_sized_range |
__cpp_lib_ranges_slide | 202202L | (C++23) | ranges::slide_view |
__cpp_lib_ranges_stride | 202207L | (C++23) | ranges::stride_view |
__cpp_lib_ranges_to_container | 202202L | (C++23) | ranges::to |
__cpp_lib_ranges_as_input | 202502L | (C++26) | ranges::as_input_view |
__cpp_lib_ranges_zip | 202110L | (C++23) |
ranges::zip_view, ranges::zip_transform_view, ranges::adjacent_view, ranges::adjacent_transform_view |
Пример
#include <iostream>
#include <ranges>
int main()
{
auto const ints = {0, 1, 2, 3, 4, 5};
auto even = [](int i) { return 0 == i % 2; };
auto square = [](int i) { return i * i; };
// the "pipe" syntax of composing the views:
for (int i : ints | std::views::filter(even) | std::views::transform(square))
std::cout << i << ' ';
std::cout << '\n';
// a traditional "functional" composing syntax:
for (int i : std::views::transform(std::views::filter(ints, even), square))
std::cout << i << ' ';
}
Вывод:
0 4 16 0 4 16
Отчёты об исправлении дефектов
Следующие отчёты об исправлении дефектов, меняющие поведение, были применены задним числом к ранее опубликованным стандартам C++.
| DR | Применён к | Опубликованное поведение | Корректное поведение |
|---|---|---|---|
|
LWG 3509 (P2281R1) | C++20 | было неясно, как объекты адаптеров диапазонов связывают завершающие аргументы | они связываются по значению |
| LWG 3948 | C++23 |
possibly-const-range и as-const-pointerне были объявлены с noexcept | объявлены с noexcept |
| LWG 4027 | C++23 |
possibly-const-range не добавлял квалификатор constдля диапазонов, которые уже моделировали constant_range | добавляет квалификатор const для таких диапазонов |
| LWG 4112 | C++20 |
has-arrow не требовал, чтобы i имел квалификатор const | требует этого |
См. также
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/ranges