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

std::ranges::range

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

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



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

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


 
<tbody> </tbody>
Определено в заголовочном файле <ranges>
template< class T > concept range = requires(T& t) { ranges::begin(t); // сохранение равенства для прямых итераторов ranges::end (t); };

Концепт range определяет требования к типу, который позволяет выполнять итерацию по своим элементам, предоставляя итератор и ограничитель, которые обозначают элементы диапазона.

Требования семантики

Учитывая выражение E такое, что decltype((E)) равно T, T моделирует range, только если

  • [ranges::begin(E), ranges::end(E)) обозначают диапазон, и
  • оба ranges::begin(E) и ranges::end(E) амортизируются с постоянным временем и не меняют значение E способом, используемым для выражений, сохраняющих равенство, и
  • если тип ranges::begin(E) моделирует forward_iterator, ranges::begin(E) сохраняет равенство (другими словами, прямые итераторы поддерживают многопроходные алгоритмы)

Примечание. В приведённом выше определении требуемые выражения ranges::begin(t) и ranges::end(t) не требуют неявные варианты выражения.

Примечание

Типичный класс range должен предоставлять только две функции:

  1. Функция-элемент begin(), тип возвращаемого значения которой моделирует input_or_output_iterator.
  2. Функция-элемент end(), тип возвращаемого значения которой моделирует sentinel_for<It>, где It это тип возвращаемого значения begin().

Альтернативно, они могут быть функциями, не являющимися элементами, которые можно найти с помощью поиска, зависящего от аргументов.

Пример

#include <iostream>
#include <ranges>
#include <vector>
 
template <typename T>
struct range_t : private T {
    using T::begin, T::end; /*...*/
};
static_assert(std::ranges::range< range_t<std::vector<int>> >);

template <typename T> struct scalar_t { T t{}; /* нет begin/end */ };
static_assert(not std::ranges::range< scalar_t<int> >);
 
int main() {
    if constexpr (range_t<std::vector<int>> r; std::ranges::range<decltype(r)>) {
        std::cout << "r диапазон\n";
    }

    if constexpr (scalar_t<int> s; not std::ranges::range<decltype(s)>) {
        std::cout << "s не диапазон\n";
    }
}

Вывод:

r диапазон
s не диапазон