std::ranges::range
Материал из cppreference.com
<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 должен предоставлять только две функции:
- Функция-элемент
begin(), тип возвращаемого значения которой моделируетinput_or_output_iterator. - Функция-элемент
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 не диапазон