Библиотека диапазонов (C++20)
Библиотека диапазонов является расширением и обобщением библиотек алгоритмов и итераторов, что делает их более мощными, составными и менее подверженным ошибкам.
Библиотека создаёт и управляет представлениями диапазонов, облегчёнными объектами, которые косвенно представляют итерируемые последовательности (диапазонов). Диапазоны это абстракция над
- пары итераторов
[начало,конец), например диапазоны, созданные неявным преобразованием из контейнеров. Все алгоритмы, использующие пары итераторов, теперь имеют перегрузки, которые принимают диапазоны (например, ranges::sort) - подсчитанные последовательности начало
+[0,размер), т.е. диапазон, возвращённый views::counted - условно-завершённые последовательности
[начало,предикат), например диапазон, возвращаемый views::take_while - неограниченные последовательности
[начало,..), например диапазон, возвращённый views::iota
Библиотека диапазонов включает алгоритмы диапазонов, которые применяются к диапазонам активно, и адаптеры диапазонов, которые применяются к представлениям лениво. Адаптеры могут быть объединены в конвейеры, чтобы их действия происходили по мере повторения представления.
<tbody> </tbody>| Определено в заголовочном файле <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) |
тип заполнителя, указывающий, что итератор или поддиапазон не должны быть возвращены, так как они будут висячими (класс) |
получает тип итератора или тип поддиапазона из 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 (концепт) |
Преобразования диапазонов | |
Определены в заголовочном файле
<ranges> | |
(C++23) |
создаёт непросматриваемый объект из входного диапазона (шаблон функции) |
Представления | |
Определены в заголовочном файле
<ranges> | |
(C++20) |
шаблон вспомогательного класса для определения view, используя любопытно повторяющийся образец шаблон (шаблон класса) |
(C++20) |
объединяет пару итератор-ограничитель в view (шаблон класса) |
Фабрики диапазонов
Определены в заголовочном файле
<ranges> | |
Определены в пространстве имён
std::ranges | |
пустой view без элементов (шаблон класса) (шаблонная переменная) | |
view, который содержит единственный элемент указанного значения (шаблон класса) (объект точки настройки) | |
(C++20) |
view, состоящий из последовательности, сгенерированной путём многократного увеличения начального значения (шаблон класса) (объект точки настройки) |
view, состоящий из элементов, полученных последовательным применением operator>> к соответствующему входному потоку (шаблон класса) (объект точки настройки) | |
view, состоящее из последовательности сгенерированной путём повторного создания одного и того же значения (шаблон класса) (объект точки настройки) | |
Адаптеры диапазонов
Определены в заголовочном файле
<ranges> | |
Определены в пространстве имён
std::ranges | |
| вспомогательный шаблон базового класса для определения объекта замыкания адаптера диапазона (шаблон класса) | |
(C++20) |
view, который включает все элементы range (псевдоним шаблона) (объект адаптера диапазона) |
(C++20) |
view из элементов некоторого другого range (шаблон класса) |
(C++20) |
view с уникальным владельцем некоторого range (шаблон класса) |
view, который состоит из элементов range, который соответствует предикату (шаблон класса) (объект адаптера диапазона) | |
view последовательности, которая применяет функцию преобразования к каждому элементу (шаблон класса) (объект адаптера диапазона) | |
(C++20) |
view, состоящий из первых N элементов другого view (шаблон класса) (объект адаптера диапазона) |
view, состоящий из начальных элементов другого view, до первого элемента, для которого предикат не вернёт false (шаблон класса) (объект адаптера диапазона) | |
(C++20) |
view, состоящий из элементов другого view, пропуская первые N элементов (шаблон класса) (объект адаптера диапазона) |
view, состоящий из элементов другого view, пропуская начальную подпоследовательность элементов до первого элемента, для которого предикат вернёт false (шаблон класса) (объект адаптера диапазона) | |
(C++20) |
view, состоящий из последовательности, полученной уплотнением view, состоящего из range (шаблон класса) (объект адаптера диапазона) |
view по поддиапазонам, полученным в результате разделения другого view с использованием разделителя (шаблон класса) (объект адаптера диапазона) | |
view по поддиапазонам, полученным в результате разделения другого view с использованием разделителя (шаблон класса) (объект адаптера диапазона) | |
(C++20) |
создаёт поддиапазон из итератора и счётчика (объект точки настройки) |
преобразует view в common_range (шаблон класса) (объект адаптера диапазона) | |
view, который перебирает элементы другого двунаправленного представления в обратном порядке (шаблон класса) (объект адаптера диапазона) | |
принимает view, состоящий из tuple-like значений, и числа N, и создаёт view из Nго элемента каждого кортежа (шаблон класса) (объект адаптера диапазона) | |
(C++20) |
принимает view, состоящий из парных значений, и создаёт view первых элементов каждой пары (шаблон класса) (объект адаптера диапазона) |
принимает view, состоящий из парных значений, и создаёт view из вторых элементов каждой пары (шаблон класса) (объект адаптера диапазона) | |
view, который отображает каждый элемент адаптированной последовательности в кортеж как позиции элемента, так и его значения (шаблон класса) (объект адаптера диапазона) | |
(C++23) |
view, состоящий из кортежей ссылок на соответствующие элементы адаптированных представлений (шаблон класса) (объект точки настройки) |
view, состоящий из кортежей результатов применения функции преобразования к соответствующим элементам адаптированных представлений (шаблон класса) (объект точки настройки) | |
view, состоящий из кортежей ссылок на соседние элементы адаптированного представления (шаблон класса) (объект адаптера диапазона) | |
view, состоящий из кортежей результатов применения функции преобразования к смежным элементам адаптированного представления (шаблон класса) (объект адаптера диапазона) | |
view, состоящее из последовательности, полученной путём выравнивания представления диапазонов, с разделителем между элементами (шаблон класса) (объект адаптера диапазона) | |
view, элемент Mый которого является view над Mый через (M + N - 1)ый элементы другого view (шаблон класса) (объект адаптера диапазона) | |
диапазон нескольких view, которые представляют собой неперекрывающиеся последовательные фрагменты элементов другого view размера N (шаблон класса) (объект адаптера диапазона) | |
разбивает view на поддиапазоны между каждой парой смежных элементов, для которых данный предикат возвращает false (шаблон класса) (объект адаптера диапазона) | |
преобразует view в constant_range (шаблон класса) (объект адаптера диапазона) | |
view последовательность, которая приводит каждый элемент к rvalue (шаблон класса) (объект адаптера диапазона) | |
view, состоящее из элементов другого view, перемещаюемся по N элементам за раз (шаблон класса) (объект адаптера диапазона) | |
view, состоящее из кортежей результатов, вычисленных с помощью n-арного декартова произведения адаптированных представлений (шаблон класса) (объект точки настройки) | |
Генераторы диапазонов
Определены в заголовочном файле
<generator> | |
Определены в пространстве имён
std | |
(C++23) |
view, представляющий синхронный генератор сопрограмм (шаблон класса) |
Вспомогательные элементы
Объекты адаптеров диапазонов
Смотрите RangeAdaptorObject (RAO).
Объекты замыкания адаптеров диапазонов
Смотрите RangeAdaptorClosureObject (RACO).
Объекты точек настройки
Смотрите Объект точек настройки (CPO).
Присваиваемая оболочка
Некоторые адаптеры диапазона упаковывают свои элементы или функциональные объекты в копируемый блок (до C++23)перемещаемый блок (начиная с C++23). Оболочка дополняет обёрнутый объект возможностью присваивания, когда это необходимо.
Нераспространяющийся кеш
Некоторые адаптеры диапазона указаны в терминах шаблона класса non-propagating-cache только для описания, который ведёт себя почти так же, как std::optional<T> (отличия смотрите в описании).
| Этот раздел не завершён Причина: Создайте страницу для non-propagating-cache [range.nonprop.cache] |
Помощники объекта точки настройки
<tbody> </tbody> 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*/ возвращает константный диапазон r, если это глубоко константный диапазон; в противном случае возвращает r без приведения типов./*as-const-pointer*/ возвращает указатель на объект константного типа.Помощники адаптеров диапазонов
<tbody> </tbody> 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 как левостороннее значение.Вспомогательные концепты
Следующие концепты только для описания и используются для нескольких типов, но они не являются частями интерфейса стандартной библиотеки.
<tbody> </tbody> 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) | (только для пояснения*) |
Примечание
| Макрос тест функциональности | Значение | Стандарт | Комментарий |
|---|---|---|---|
__cpp_lib_generator |
202207L |
(C++23) | std::generator – синхронный генератор сопрограмм для диапазонов |
__cpp_lib_ranges |
201911L |
(C++20) | Библиотека диапазонов и алгоритмы с ограничениями |
202106L |
(C++20)) | Не инициализируемые по умолчанию представления | |
202110L |
(C++20)) | Представления с владением | |
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; };
// "конвейерный" синтаксис для создания представлений:
for (int i : ints | std::views::filter(even) | std::views::transform(square)) {
std::cout << i << ' ';
}
std::cout << '\n';
// традиционный "функциональный" синтаксис составления:
for (int i : std::views::transform(std::views::filter(ints, even), square)) {
std::cout << i << ' ';
}
}
Вывод:
0 4 16
0 4 16
Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
| Номер | Применён | Поведение в стандарте | Корректное поведение |
|---|---|---|---|
| LWG 3509 | C++20 | было неясно, как объекты адаптеров диапазонов связывают конечные аргументы | они связаны по значению |