Spec-Zone.ru › C++

Библиотека 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>
ranges::begin
(C++20)
возвращает итератор на начало диапазона
(объект-точка настройки)
ranges::end
(C++20)
возвращает сентинел, обозначающий конец диапазона
(объект-точка настройки)
ranges::cbegin
(C++20)
возвращает итератор на начало диапазона только для чтения
(объект-точка настройки)
ranges::cend
(C++20)
возвращает сентинел, обозначающий конец диапазона только для чтения
(объект-точка настройки)
ranges::rbegin
(C++20)
возвращает обратный итератор для диапазона
(объект-точка настройки)
ranges::rend
(C++20)
возвращает обратный конечный итератор для диапазона
(объект-точка настройки)
ranges::crbegin
(C++20)
возвращает обратный итератор для диапазона только для чтения
(объект-точка настройки)
ranges::crend
(C++20)
возвращает обратный конечный итератор для диапазона только для чтения
(объект-точка настройки)
ranges::reserve_hint
(C++26)
возвращает целое число, равное подсказке о резервировании, заданной диапазоном
(объект-точка настройки)
ranges::size
(C++20)
возвращает целое число, равное размеру диапазона
(объект-точка настройки)
ranges::ssize
(C++20)
возвращает целое число со знаком, равное размеру диапазона
(объект-точка настройки)
ranges::empty
(C++20)
проверяет, пуст ли диапазон
(объект-точка настройки)
ranges::data
(C++20)
получает указатель на начало непрерывного диапазона
(объект-точка настройки)
ranges::cdata
(C++20)
получает указатель на начало непрерывного диапазона только для чтения
(объект-точка настройки)
Примитивы диапазонов
Определено в заголовке <ranges>
ranges::iterator_tranges::const_iterator_tranges::sentinel_tranges::const_sentinel_t
(C++20)(C++23)(C++20)(C++23)
получает типы итератора и сентинела диапазона
(шаблон псевдонима)
ranges::range_difference_tranges::range_size_tranges::range_value_t
(C++20)(C++20)(C++20)
получает типы размера, разности и значения диапазона
(шаблон псевдонима)
ranges::range_reference_tranges::range_const_reference_tranges::range_rvalue_reference_tranges::range_common_reference_t
(C++20)(C++23)(C++20)(C++20)
получает ссылочные типы диапазона
(шаблон псевдонима)
Обработка висячих итераторов
Определено в заголовке <ranges>
ranges::dangling
(C++20)
тип-заполнитель, указывающий, что итератор или subrange не следует возвращать, поскольку он станет висячим
(класс)
ranges::borrowed_iterator_tranges::borrowed_subrange_t
(C++20)
получает тип итератора или тип subrange для borrowed_range
(шаблон псевдонима)
Другие вспомогательные средства
Определено в заголовке <ranges>
ranges::elements_of
(C++23)
помечает диапазон, который следует обрабатывать как последовательность, а не как одно значение
(шаблон класса)
Концепции диапазонов
Определено в заголовке <ranges>
ranges::range
(C++20)
задаёт требования к типу, являющемуся диапазоном, то есть предоставляющему итератор begin и сентинел end
(концепция)
ranges::borrowed_range
(C++20)
задаёт требования к типу, являющемуся range, итераторы которого, полученные из выражения этого типа, можно безопасно возвращать без риска их превращения в висячие
(концепция)
ranges::approximately_sized_range
(C++26)
задаёт требования к диапазону, способному оценить свой размер за постоянное время
(концепция)
ranges::sized_range
(C++20)
задаёт требования к диапазону, размер которого известен за постоянное время
(концепция)
ranges::view
(C++20)
задаёт требования к диапазону-представлению, то есть копирование, перемещение и присваивание которого выполняются за постоянное время
(концепция)
ranges::input_range
(C++20)
задаёт требования к диапазону, тип итератора которого удовлетворяет концепции input_iterator
(концепция)
ranges::output_range
(C++20)
задаёт требования к диапазону, тип итератора которого удовлетворяет концепции output_iterator
(концепция)
ranges::forward_range
(C++20)
задаёт требования к диапазону, тип итератора которого удовлетворяет концепции forward_iterator
(концепция)
ranges::bidirectional_range
(C++20)
задаёт требования к диапазону, тип итератора которого удовлетворяет концепции bidirectional_iterator
(концепция)
ranges::random_access_range
(C++20)
задаёт требования к диапазону, тип итератора которого удовлетворяет концепции random_access_iterator
(концепция)
ranges::contiguous_range
(C++20)
задаёт требования к диапазону, тип итератора которого удовлетворяет концепции contiguous_iterator
(концепция)
ranges::common_range
(C++20)
задаёт требования к диапазону, типы итератора и сентинела которого совпадают
(концепция)
ranges::viewable_range
(C++20)
задаёт требования, которым должен удовлетворять range, чтобы его можно было безопасно преобразовать в view
(концепция)
ranges::constant_range
(C++23)
задаёт требования к диапазону с элементами только для чтения
(концепция)
sized-random-access-range
(C++26)
задаёт требования к диапазону, размер которого известен за постоянное время и элементы которого доступны произвольно
(концепция, используемая только для пояснения*)
Преобразования диапазонов
Определено в заголовке <ranges>
ranges::to
(C++23)
создаёт новый объект, не являющийся представлением, из входного диапазона
(шаблон функции)
Представления
Определено в заголовке <ranges>
ranges::view_interface
(C++20)
вспомогательный шаблон класса для определения view с использованием идиомы рекурсивного шаблона
(шаблон класса)
ranges::subrange
(C++20)
объединяет пару «итератор — сентинел» в view
(шаблон класса)

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

Определено в заголовке <ranges>
Определено в пространстве имён std::ranges
ranges::empty_viewviews::empty
(C++20)
пустое view без элементов
(шаблон класса) (шаблон переменной)
ranges::single_viewviews::single
(C++20)
view, содержащий один элемент с заданным значением
(шаблон класса) (объект-точка настройки)
ranges::iota_viewviews::iota
(C++20)
view, состоящий из последовательности, полученной многократным увеличением начального значения
(шаблон класса) (объект-точка настройки)
views::indices
(C++26)
view, генерирующий последовательность возрастающих значений от 0 до n
(объект-точка настройки)
ranges::repeat_viewviews::repeat
(C++23)
view, состоящий из последовательности, генерируемой многократным созданием одного и того же значения
(шаблон класса) (объект-точка настройки)
ranges::basic_istream_viewviews::istream
(C++20)
view, состоящий из элементов, полученных последовательным применением operator>> к связанному входному потоку
(шаблон класса) (объект-точка настройки)

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

Определено в заголовочном файле <ranges>
Определено в пространстве имён std::ranges
ranges::range_adaptor_closure
(C++23)
вспомогательный базовый шаблон класса для определения объекта-замыкания адаптера диапазона
(шаблон класса)
views::all_tviews::all
(C++20)
view, включающее все элементы range
(шаблон псевдонима) (объект-адаптер диапазона)
ranges::ref_view
(C++20)
view элементов другого range
(шаблон класса)
ranges::owning_view
(C++20)
view, которому принадлежит некоторый range
(шаблон класса)
ranges::as_rvalue_viewviews::as_rvalue
(C++23)
view последовательности, преобразующее каждый элемент в rvalue
(шаблон класса) (объект-адаптер диапазона)
ranges::filter_viewviews::filter
(C++20)
view, состоящее из элементов range, удовлетворяющих предикату
(шаблон класса) (объект-адаптер диапазона)
ranges::transform_viewviews::transform
(C++20)
view последовательности, применяющее функцию преобразования к каждому элементу
(шаблон класса) (объект-адаптер диапазона)
ranges::take_viewviews::take
(C++20)
view, состоящее из первых N элементов другого view
(шаблон класса) (объект-адаптер диапазона)
ranges::take_while_viewviews::take_while
(C++20)
view, состоящее из начальных элементов другого view до первого элемента, для которого предикат возвращает false
(шаблон класса) (объект-адаптер диапазона)
ranges::drop_viewviews::drop
(C++20)
view, состоящее из элементов другого view без первых N элементов
(шаблон класса) (объект-адаптер диапазона)
ranges::drop_while_viewviews::drop_while
(C++20)
view, состоящее из элементов другого view без начальной подпоследовательности элементов до первого элемента, для которого предикат возвращает false
(шаблон класса) (объект-адаптер диапазона)
ranges::join_viewviews::join
(C++20)
view, состоящее из последовательности, полученной путём разворачивания view из ranges
(шаблон класса) (объект-адаптер диапазона)
ranges::join_with_viewviews::join_with
(C++23)
view, состоящее из последовательности, полученной путём разворачивания представления диапазонов с разделителем между элементами
(шаблон класса) (объект-адаптер диапазона)
ranges::lazy_split_viewviews::lazy_split
(C++20)
view подпоследовательностей, полученных разбиением другого view с помощью разделителя
(шаблон класса) (объект-адаптер диапазона)
ranges::split_viewviews::split
(C++20)
view подпоследовательностей, полученных разбиением другого view с помощью разделителя
(шаблон класса) (объект-адаптер диапазона)
ranges::concat_viewviews::concat
(C++26)
view, состоящее из конкатенации адаптированных представлений
(шаблон класса) (объект точки настройки)
views::counted
(C++20)
создаёт подпоследовательность из итератора и количества элементов
(объект точки настройки)
ranges::common_viewviews::common
(C++20)
преобразует view в common_range
(шаблон класса) (объект-адаптер диапазона)
ranges::reverse_viewviews::reverse
(C++20)
view, перебирающее элементы другого двунаправленного представления в обратном порядке
(шаблон класса) (объект-адаптер диапазона)
ranges::as_const_viewviews::as_const
(C++23)
преобразует view в constant_range
(шаблон класса) (объект-адаптер диапазона)
ranges::elements_viewviews::elements
(C++20)
принимает view, состоящее из значений tuple-like, и число N и создаёт view из N-го элемента каждого кортежа
(шаблон класса) (объект-адаптер диапазона)
ranges::keys_viewviews::keys
(C++20)
принимает view, состоящее из пароподобных значений, и создаёт view из первых элементов каждой пары
(шаблон класса) (объект-адаптер диапазона)
ranges::values_viewviews::values
(C++20)
принимает view, состоящее из пароподобных значений, и создаёт view из вторых элементов каждой пары
(шаблон класса) (объект-адаптер диапазона)
ranges::enumerate_viewviews::enumerate
(C++23)
view, сопоставляющее каждому элементу адаптированной последовательности кортеж из позиции элемента и его значения
(шаблон класса) (объект-адаптер диапазона)
ranges::zip_viewviews::zip
(C++23)
view, состоящее из кортежей ссылок на соответствующие элементы адаптированных представлений
(шаблон класса) (объект точки настройки)
ranges::zip_transform_viewviews::zip_transform
(C++23)
view, состоящее из результатов применения функции преобразования к соответствующим элементам адаптированных представлений
(шаблон класса) (объект точки настройки)
ranges::adjacent_viewviews::adjacent
(C++23)
view, состоящее из кортежей ссылок на соседние элементы адаптированного представления
(шаблон класса) (объект-адаптер диапазона)
views::pairwise
(C++23)
view, состоящее из пар ссылок на соседние элементы адаптированного представления
(объект точки настройки)
ranges::adjacent_transform_viewviews::adjacent_transform
(C++23)
view, состоящее из результатов применения функции преобразования к соседним элементам адаптированного представления
(шаблон класса) (объект-адаптер диапазона)
views::pairwise_transform
(C++23)
view, состоящее из результатов применения функции преобразования к каждой паре соседних элементов адаптированного представления
(объект точки настройки)
ranges::chunk_viewviews::chunk
(C++23)
диапазон из views, представляющих собой неперекрывающиеся последовательные блоки элементов другого view размером N
(шаблон класса) (объект-адаптер диапазона)
ranges::slide_viewviews::slide
(C++23)
view, M-й элемент которого является view над элементами с M-го по (M + N - 1)-й другого view
(шаблон класса) (объект-адаптер диапазона)
ranges::chunk_by_viewviews::chunk_by
(C++23)
разбивает view на подпоследовательности между каждой парой соседних элементов, для которых заданный предикат возвращает false
(шаблон класса) (объект-адаптер диапазона)
ranges::stride_viewviews::stride
(C++23)
view, состоящее из элементов другого view с переходом через каждые N элементов
(шаблон класса) (объект-адаптер диапазона)
ranges::cartesian_product_viewviews::cartesian_product
(C++23)
view, состоящее из кортежей результатов вычисления n-арного декартова произведения адаптированных представлений
(шаблон класса) (объект точки настройки)
ranges::cache_latest_viewviews::cache_latest
(C++26)
view, кэширующее последний элемент базовой последовательности, к которому обращались
(шаблон класса) (объект-адаптер диапазона)
ranges::as_input_viewviews::as_input
(C++26)
преобразует view в диапазон, являющийся только input_range и не являющийся common_range
(шаблон класса) (объект-адаптер диапазона)

Генераторы диапазонов (с C++23)

Определено в заголовочном файле <generator>
Определено в пространстве имён std
generator
(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) (только для описания*)
1) Для типа целочисленного вида целочисленного вида T:
  • Если T является целочисленным типом, /*make-signed-like-t*/<T> — это std::make_signed_t<T>.
  • В противном случае /*make-signed-like-t*/<T> — это соответствующий знаковый тип целочисленного вида с неуказанным именем и той же шириной, что и T.
2) Для типа целочисленного вида T:
  • Если T является целочисленным типом, /*make-unsigned-like-t*/<T> — это std::make_unsigned_t<T>.
  • В противном случае /*make-signed-like-t*/<T> — это соответствующий беззнаковый тип целочисленного вида с неуказанным именем и той же шириной, что и T.
3) Явно преобразует 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) (только для описания*)

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

1) /*possibly-const-range*/ возвращает версию r с квалификатором const, если constR удовлетворяет требованиям input_range; в противном случае возвращает r без каких-либо преобразований.
2) /*as-const-pointer*/ возвращает указатель на объект константного типа.

Вспомогательные средства для адаптеров диапазонов

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

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

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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API