Defined in header `<ranges>` | ||
---|---|---|

template< class T > concept range = requires( T& t ) { ranges::begin(t); // equality-preserving for forward iterators ranges::end (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.

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.

#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"; }

Output:

r is a range s is not a range

© cppreference.com

Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.

https://en.cppreference.com/w/cpp/ranges/range