std::ranges::range
Определено в заголовке <ranges> | ||
|---|---|---|
template< class T >
concept range = requires( T& t ) {
ranges::begin(t); // equality-preserving for forward iterators
ranges::end (t);
};
| (с C++20) |
Концепция 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)является сохраняющим равенство (другими словами, итераторы вперёд поддерживают многопроходные алгоритмы).
Примечания
Типичный класс 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 {}; /* no 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 is a range\n";
if constexpr (scalar_t<int> s; not std::ranges::range<decltype(s)>)
std::cout << "s is not a range\n";
}Вывод:
r is a range s is not a range
Отчёты о дефектах
Следующие отчёты о дефектах, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применено к | Поведение, как опубликовано | Корректное поведение |
|---|---|---|---|
| LWG 3915 | C++20 |
ranges::begin(t) и ranges::end(t)не требовали неявных вариантов выражений | удалено избыточное описание |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/ranges/range