close
Пространства имён
Варианты
Действия

Библиотека диапазонов (C++20)

Материал из cppreference.com
< cpp
 
 
Библиотека диапазонов
Доступ к диапазонам
Преобразования диапазонов
(C++23)

Примитивы диапазонов



Обработка висячих итераторов
Концепты диапазонов
Представления

Фабрики диапазонов
Адаптеры диапазонов
Генераторы диапазонов
Объекты адаптеров диапазонов
Объекты замыкания адаптеров диапазонов
Вспомогательные элементы
(до C++23)(C++23)


 

Библиотека диапазонов является расширением и обобщением библиотек алгоритмов и итераторов, что делает их более мощными, составными и менее подверженным ошибкам.

Библиотека создаёт и управляет представлениями диапазонов, облегчёнными объектами, которые косвенно представляют итерируемые последовательности (диапазонов). Диапазоны это абстракция над

  • пары итераторов [началоконец), например диапазоны, созданные неявным преобразованием из контейнеров. Все алгоритмы, использующие пары итераторов, теперь имеют перегрузки, которые принимают диапазоны (например, 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>
возвращает итератор на начало диапазона
(объект точки настройки) [править]
возвращает ограничитель, указывающий на конец диапазона
(объект точки настройки) [править]
возвращает итератор на начало диапазона только для чтения
(объект точки настройки) [править]
возвращает ограничитель, указывающий на конец диапазона, доступного только для чтения
(объект точки настройки) [править]
возвращает обратный итератор на диапазон
(объект точки настройки) [править]
возвращает обратный конечный итератор диапазона
(объект точки настройки) [править]
возвращает обратный итератор на диапазон только для чтения
(объект точки настройки) [править]
возвращает обратный конечный итератор на диапазон только для чтения
(объект точки настройки) [править]
возвращает целое число, равное размеру диапазона
(объект точки настройки) [править]
возвращает целое число со знаком, равное размеру диапазона
(объект точки настройки) [править]
проверяет, пуст ли диапазон
(объект точки настройки) [править]
получает указатель на начало непрерывного диапазона
(объект точки настройки) [править]
получает указатель на начало непрерывного диапазона, доступного только для чтения
(объект точки настройки) [править]
Примитивы диапазонов
Определены в заголовочном файле <ranges>
получает ассоциированные типы диапазона
(псевдоним шаблона) [править]
Обработка висячих итераторов
Определены в заголовочном файле <ranges>
тип заполнителя, указывающий, что итератор или поддиапазон не должны быть возвращены, так как они будут висячими
(класс) [править]
получает тип итератора или тип поддиапазона из borrowed_range
(псевдоним шаблона) [править]
Концепты диапазонов
Определены в заголовочном файле <ranges>
указывает, что тип является диапазоном, то есть предоставляет итератор begin и ограничитель end
(концепт) [править]
указывает, что тип является range, и итераторы, полученные из его выражения, могут быть безопасно возвращены без опасности зависания
(концепт) [править]
указывает, что диапазон узнаёт свой размер за константное время
(концепт) [править]
указывает, что диапазон является представлением, то есть имеет постоянное время копирования/перемещения/присваивания
(концепт) [править]
указывает диапазон, тип итератора которого соответствует input_iterator
(концепт) [править]
указывает диапазон, тип итератора которого соответствует output_iterator
(концепт) [править]
указывает диапазон, тип итератора которого соответствует forward_iterator
(концепт) [править]
указывает диапазон, тип итератора которого соответствует bidirectional_iterator
(концепт) [править]
указывает диапазон, тип итератора которого соответствует random_access_iterator
(концепт) [править]
указывает диапазон, тип итератора которого соответствует contiguous_iterator
(концепт) [править]
указывает, что диапазон имеет идентичные типы итератора и ограничителя
(концепт) [править]
определяет требования к range для безопасного преобразования в view
(концепт) [править]
Преобразования диапазонов
Определены в заголовочном файле <ranges>
создаёт непросматриваемый объект из входного диапазона
(шаблон функции) [править]
Представления
Определены в заголовочном файле <ranges>
шаблон вспомогательного класса для определения view, используя любопытно повторяющийся образец шаблон
(шаблон класса) [править]
объединяет пару итератор-ограничитель в view
(шаблон класса) [править]

Фабрики диапазонов

Определены в заголовочном файле <ranges>
Определены в пространстве имён std::ranges
пустой view без элементов
(шаблон класса) (шаблонная переменная) [править]
view, который содержит единственный элемент указанного значения
(шаблон класса) (объект точки настройки) [править]
view, состоящий из последовательности, сгенерированной путём многократного увеличения начального значения
(шаблон класса) (объект точки настройки) [править]
view, состоящий из элементов, полученных последовательным применением operator>> к соответствующему входному потоку
(шаблон класса) (объект точки настройки) [править]
view, состоящее из последовательности сгенерированной путём повторного создания одного и того же значения
(шаблон класса) (объект точки настройки) [править]

Адаптеры диапазонов

Определены в заголовочном файле <ranges>
Определены в пространстве имён std::ranges
вспомогательный шаблон базового класса для определения объекта замыкания адаптера диапазона
(шаблон класса) [править]
view, который включает все элементы range
(псевдоним шаблона) (объект адаптера диапазона) [править]
view из элементов некоторого другого range
(шаблон класса) [править]
view с уникальным владельцем некоторого range
(шаблон класса) [править]
view, который состоит из элементов range, который соответствует предикату
(шаблон класса) (объект адаптера диапазона) [править]
view последовательности, которая применяет функцию преобразования к каждому элементу
(шаблон класса) (объект адаптера диапазона) [править]
view, состоящий из первых N элементов другого view
(шаблон класса) (объект адаптера диапазона) [править]
view, состоящий из начальных элементов другого view, до первого элемента, для которого предикат не вернёт false
(шаблон класса) (объект адаптера диапазона) [править]
view, состоящий из элементов другого view, пропуская первые N элементов
(шаблон класса) (объект адаптера диапазона) [править]
view, состоящий из элементов другого view, пропуская начальную подпоследовательность элементов до первого элемента, для которого предикат вернёт false
(шаблон класса) (объект адаптера диапазона) [править]
view, состоящий из последовательности, полученной уплотнением view, состоящего из range
(шаблон класса) (объект адаптера диапазона) [править]
view по поддиапазонам, полученным в результате разделения другого view с использованием разделителя
(шаблон класса) (объект адаптера диапазона) [править]
view по поддиапазонам, полученным в результате разделения другого view с использованием разделителя
(шаблон класса) (объект адаптера диапазона) [править]
создаёт поддиапазон из итератора и счётчика
(объект точки настройки) [править]
преобразует view в common_range
(шаблон класса) (объект адаптера диапазона) [править]
view, который перебирает элементы другого двунаправленного представления в обратном порядке
(шаблон класса) (объект адаптера диапазона) [править]
принимает view, состоящий из tuple-like значений, и числа N, и создаёт view из Nго элемента каждого кортежа
(шаблон класса) (объект адаптера диапазона) [править]
принимает view, состоящий из парных значений, и создаёт view первых элементов каждой пары
(шаблон класса) (объект адаптера диапазона) [править]
принимает view, состоящий из парных значений, и создаёт view из вторых элементов каждой пары
(шаблон класса) (объект адаптера диапазона) [править]
view, который отображает каждый элемент адаптированной последовательности в кортеж как позиции элемента, так и его значения
(шаблон класса) (объект адаптера диапазона) [править]
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> (отличия смотрите в описании).

Помощники объекта точки настройки

<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) (только для пояснения*)

Некоторые объекты точки настройки доступа к диапазону задаются в терминах этих шаблонов функций только для описания.

1) /*possibly-const-range*/ возвращает константный диапазон r, если это глубоко константный диапазон; в противном случае возвращает r без приведения типов.
2) /*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) (только для пояснения*)

Некоторые адаптеры диапазона указаны в терминах этих шаблонов функций только для пояснения.

1) /*tuple-transform*/ возвращает новый кортеж, созданный путём применения f к каждому элементу tuple.
2) /*tuple-for-each*/ применяет f к каждому элементу tuple и ничего не возвращает.
3) /*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 было неясно, как объекты адаптеров диапазонов связывают конечные аргументы они связаны по значению

Смотрите также