Библиотека диапазонов (C++20)
Библиотека диапазонов является расширением и обобщением библиотек алгоритмов и итераторов, делающих их более мощными благодаря возможности композиции и снижению вероятности ошибок.
Библиотека создает и манипулирует представлениями диапазонов, легкими объектами, которые косвенно представляют итерируемые последовательности (диапазоны). Диапазоны представляют собой абстракцию над
-
[begin,end)– парами итераторов, например, диапазоны, созданные неявным преобразованием из контейнеров. Все алгоритмы, принимающие пары итераторов, теперь имеют перегрузки, принимающие диапазоны (например,ranges::sort) - begin
+[0,size)– последовательности со счётчиком, например, диапазон, возвращаемыйviews::counted -
[begin,предикатом)– последовательности с условной конечностью, например, диапазон, возвращаемыйviews::take_while -
[begin,..)– неограниченные последовательности, например, диапазон, возвращаемыйviews::iota
Библиотека диапазонов включает алгоритмы для диапазонов, которые применяются к диапазонам немедленно, и адаптеры диапазонов, которые применяются к представлениям лениво. Адаптеры могут быть объединены в цепочки, так что их действия выполняются при итерировании представления.
Определено в заголовке <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++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++20) | определяет, что тип является диапазоном, то есть он предоставляет итератор begin и страж end (концепция) |
|
(C++20) | определяет, что тип является range, и итераторы, полученные от выражения, могут быть безопасно возвращены без опасности возникновения висячих (концепция) |
|
(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) | определяет, что диапазон имеет только элементы для чтения (концепция) |
Преобразования диапазонов |
|
Определено в заголовке <ranges> |
|
|---|---|
|
(C++23) | создает новый объект без представления из входного диапазона (шаблон функции) |
Представления |
|
Определено в заголовке <ranges> |
|
|
(C++20) | вспомогательный шаблон класса для определения view, используя шаблон с повторяющимся шаблоном (шаблон класса) |
|
(C++20) | объединяет пару итератор-конечная точка в view (шаблон класса) |
Фабрики диапазонов
Определено в заголовке <ranges> |
|
|---|---|
Определено в пространстве имен std::ranges |
|
|
(C++20) | пустое view без элементов(шаблон класса) (шаблон переменной) |
|
(C++20) | view, содержащее один элемент заданного значения(шаблон класса) (объект точки кастомизации) |
|
(C++20) | view, состоящее из последовательности, генерируемой многократным инкрементированием начального значения(шаблон класса) (объект точки кастомизации) |
|
(C++20) | view, состоящее из элементов, получаемых последовательным применением operator>> к связанному потоку ввода(шаблон класса) (объект точки кастомизации) |
|
(C++23) | view, состоящее из генерируемой последовательности, повторно производящей одно и то же значение(шаблон класса) (объект точки кастомизации) |
Адаптеры диапазонов
Определено в заголовке <ranges> |
|
|---|---|
Определено в пространстве имен std::ranges |
|
|
(C++23) | шаблон базового класса-помощника для определения объекта адаптера диапазона (шаблон класса) |
|
(C++20) | view, содержащий все элементы range(шаблон псевдонима) (объект адаптера диапазона) |
|
(C++20) | view элементов другого range(шаблон класса) |
|
(C++20) | view с уникальной собственностью на некоторый range(шаблон класса) |
|
(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 range(шаблон класса) (объект адаптера диапазона) |
|
(C++20) | view над поддиапазонами, полученными путем разделения другого view с помощью разделителя(шаблон класса) (объект адаптера диапазона) |
|
(C++20) | view над поддиапазонами, полученными путем разделения другого view с помощью разделителя(шаблон класса) (объект адаптера диапазона) |
|
(C++20) | создает поддиапазон из итератора и счетчика (объект точки кастомизации) |
|
(C++20) | преобразует view в common_range(шаблон класса) (объект адаптера диапазона) |
|
(C++20) | view, итерирующийся по элементам другого двунаправленного диапазона в обратном порядке(шаблон класса) (объект адаптера диапазона) |
|
(C++20) | берет view, состоящий из tuple-like значений и числа N, и производит view N-го элемента каждой кортежи(шаблон класса) (объект адаптера диапазона) |
|
(C++20) | берет view, состоящий из парных значений, и производит view первых элементов каждой пары(шаблон класса) (объект адаптера диапазона) |
|
(C++20) | берет view, состоящий из парных значений, и производит view вторых элементов каждой пары(шаблон класса) (объект адаптера диапазона) |
|
(C++23) | a view that maps each element of adapted sequence to a tuple of both the element's position and its value(class template) (range adaptor object) |
|
(C++23) | a view consisting of tuples of references to corresponding elements of the adapted views(class template) (customization point object) |
|
(C++23) | a view consisting of tuples of results of application of a transformation function to corresponding elements of the adapted views(class template) (customization point object) |
|
(C++23) | a view consisting of tuples of references to adjacent elements of the adapted view(class template) (range adaptor object) |
|
(C++23) | a view consisting of tuples of results of application of a transformation function to adjacent elements of the adapted view(class template) (range adaptor object) |
|
(C++23) | a view consisting of the sequence obtained from flattening a view of ranges, with the delimiter in between elements(class template) (range adaptor object) |
|
(C++23) | a view whose Mth element is a view over the Mth through (M + N - 1)th elements of another view(class template) (range adaptor object) |
|
(C++23) | a range of views that are N-sized non-overlapping successive chunks of the elements of another view(class template) (range adaptor object) |
|
(C++23) | splits the view into subranges between each pair of adjacent elements for which the given predicate returns false(class template) (range adaptor object) |
|
(C++23) | converts a view into a constant_range(class template) (range adaptor object) |
|
(C++23) | a view of a sequence that casts each element to an rvalue(class template) (range adaptor object) |
|
(C++23) | a view consisting of elements of another view, advancing over N elements at a time(class template) (range adaptor object) |
|
(C++23) | a view consisting of tuples of results calculated by the n-ary cartesian product of the adapted views(class template) (customization point object) |
Генераторы диапазонов
Определено в заголовке <generator> |
|
|---|---|
Определено в пространстве имён std |
|
|
(C++23) | A view that represents synchronous coroutine generator (class template) |
Вспомогательные элементы
Объекты адаптеров диапазонов
См. RangeAdaptorObject (РАО).
Объекты адаптеров диапазонов с замыканием
См. RangeAdaptorClosureObject (РАКО).
Объекты точек кастомизации
См. Объект точки кастомизации (ОТПК).
Обёртка с присваиванием
Некоторые адаптеры диапазонов оборачивают свои элементы или объекты функций с помощью copyable-box(до C++23)movable-box(с C++23). Обёртка дополняет оборачиваемый объект возможностью присваивания по мере необходимости.
Кэш без распространения
Некоторые адаптеры диапазонов определяются с помощью класса-шаблона без распространения, который ведет себя почти точно так же, как std::optional<T> (см. описание различий).
Помощники объектов точек кастомизации
template< ranges::input_range R >
constexpr auto& /*possibly-const-range*/(R& r) {
if constexpr (ranges::constant_range<const R> && !ranges::constant_range<R>) {
return const_cast<const R&>(r);
} else {
return r;
}
}
| (1) | (только для иллюстрации*) |
template< class T >
constexpr auto /*as-const-pointer*/( const T* p ) {
return p;
}
| (2) | (только для иллюстрации*) |
Некоторые объекты точек кастомизации доступа к диапазонам определяются с помощью этих шаблонов функций без распространения.
/*possibly-const-range*/ возвращает диапазон с модификатором const r если это глубоко-постоянный диапазон; в противном случае, возвращает r без преобразования./*as-const-pointer*/ возвращает указатель на объект константного типа.Помощники адаптеров диапазонов
template< class F, class Tuple >
constexpr auto /*tuple-transform*/( F&& f, Tuple&& tuple ) {
return std::apply([&]<class... Ts>(Ts&&... elements) {
return std::tuple<std::invoke_result_t<F&, Ts>...>(
std::invoke(f, std::forward<Ts>(elements))...
);
}, std::forward<Tuple>(tuple));
}
| (1) | (только для примера*) |
template< class F, class Tuple >
constexpr void /*tuple-for-each*/( F&& f, Tuple&& tuple ) {
std::apply([&]<class... Ts>(Ts&&... elements) {
(static_cast<void>(std::invoke(f, std::forward<Ts>(elements))), ...);
}, std::forward<Tuple>(tuple));
}
| (2) | (только для примера*) |
template< class T >
constexpr T& /*as-lvalue*/( T&& t ) {
return static_cast<T&>(t);
}
| (3) | (только для примера*) |
Некоторые адаптеры диапазонов определяются с использованием этих шаблонов функций, предназначенных только для примера.
/*tuple-transform*/ возвращает новую кортеж, построенную путём применения f к каждому элементу tuple./*tuple-for-each*/ применяет f к каждому элементу tuple и ничего не возвращает./*as-lvalue*/ передаёт rvalue 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(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) | (только для примера*) |
Примечания
| Макрос проверки наличия функции | Значение | Std | Функция |
|---|---|---|---|
__cpp_lib_generator | 202207L | (C++23) |
std::generator – синхронный генератор корутин для диапазонов |
__cpp_lib_ranges | 201911L | (C++20) | Библиотека диапазонов и ограниченные алгоритмы |
| 202106L |
(C++20) (DR) | Не-инициализируемые по умолчанию представления | |
| 202110L |
(C++20) (DR) | Представления с владением | |
| 202202L | (C++23) |
std::ranges::range_adaptor_closure |
|
| 202207L | (C++23) | Смягчение требований к адаптерам диапазонов, чтобы разрешить типы, которые можно только перемещать | |
| 202211L | (C++23) | Удаление перегрузок «ядовитых пилюль» (P2602) в ranges::begin и т.д. |
|
__cpp_lib_ranges_as_const | 202207L | (C++23) |
std::const_iterator, std::ranges::as_const_view |
__cpp_lib_ranges_as_rvalue | 202207L | (C++23) |
std::ranges::as_rvalue_view |
__cpp_lib_ranges_cartesian_product | 202207L | (C++23) |
std::ranges::cartesian_product_view |
__cpp_lib_ranges_chunk | 202202L | (C++23) |
std::ranges::chunk_view |
__cpp_lib_ranges_chunk_by | 202202L | (C++23) |
std::ranges::chunk_by_view |
__cpp_lib_ranges_enumerate | 202302L | (C++23) |
std::ranges::enumerate_view |
__cpp_lib_ranges_join_with | 202202L | (C++23) |
std::ranges::join_with_view |
__cpp_lib_ranges_repeat | 202207L | (C++23) |
std::ranges::repeat_view |
__cpp_lib_ranges_slide | 202202L | (C++23) |
std::ranges::slide_view |
__cpp_lib_ranges_stride | 202207L | (C++23) |
std::ranges::stride_view |
__cpp_lib_ranges_to_container | 202202L | (C++23) |
std::ranges::to |
__cpp_lib_ranges_zip | 202110L | (C++23) |
std::ranges::zip_view,std::ranges::zip_transform_view,std::ranges::adjacent_view,std::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 | C++20 | не было ясно, как объекты адаптеров диапазонов связывают аргументы, следующие за ними | они связаны по значению |
См. также
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/ranges