# std::ranges::range

From cppreference.com
< cpp‎ | ranges

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.

### 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 <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

Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/ranges/range&oldid=151144"