std::ranges::range
From cppreference.com
Defined in header <ranges>
|
||
template< class T > concept range = requires( T& t ) { |
(since C++20) | |
The range
concept defines the requirements of a type that allows iteration over its elements by providing an iterator and sentinel that denote the elements of the range.
Semantic requirements
Given an expression E such that decltype((E)) is T, T models range only if
- [ranges::begin(E), ranges::end(E)) denotes a range, and
- both ranges::begin(E) and ranges::end(E) are amortized constant time and do not alter the value of E in a manner observable to equality-preserving expressions, and
- if the type of ranges::begin(E) models
forward_iterator
, ranges::begin(E) is equality-preserving (in other words, forward iterators support multi-pass algorithms)
Note: In the definition above, the required expressions ranges::begin(t) and ranges::end(t) do not require implicit expression variations.
Example
Run this code
#include <ranges> #include <vector> #include <iostream> 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"; } }
Output:
r is a range s is not a range