< cpp‎ | ranges
Ranges library
Range access
Range conversions

Range primitives

Dangling iterator handling
Range concepts

Range factories
Range adaptors
Range generators
Range adaptor objects
Range adaptor closure objects
Helper items
(until C++23)(C++23)

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.


[edit] Semantic requirements

Given an expression E such that decltype((E)) is T, T models range only if

[edit] Notes

A typical range class only needs to provide two functions:

  1. A member function begin() whose return type models input_or_output_iterator.
  2. A member function end() whose return type models sentinel_for<It>, where It is the return type of begin().

Alternatively, they can be non-member functions, to be found by argument-dependent lookup.

[edit] Example

#include <iostream>
#include <ranges>
#include <vector>
template<typename T>
struct range_t : private T
    using T::begin, T::end; /* ... */
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

[edit] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
LWG 3915 C++20 ranges::begin(t) and ranges::end(t)
did not require implicit expression variations
removed the
redundant description