std::ranges::range
From cppreference.com
 
 
 
 
 
 C++ 
 Feature test macros (C++20)
 Concepts library (C++20)
 Metaprogramming library (C++11)
 Ranges library (C++20)
 Filesystem library (C++17)
 Concurrency support library (C++11)
 Execution control library (C++26)
Ranges library 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
	
		
(C++23)(C++23)
  (C++23)(C++23)
(C++23)(C++23)
  (C++26)(C++26)
(C++23)(C++23)
(C++23)(C++23)
(C++23)(C++23)
(C++23)(C++23)
  (C++23)(C++23)
(C++23)
(C++23)(C++23)
(C++23)
(C++23)(C++23)
(C++23)(C++23)
(C++23)(C++23)
(C++23)(C++23)
(C++23)(C++23)
(C++23)
    Defined in header 
 
 
<ranges> 
 template< class T >
 
 (since C++20) 
concept range = requires( T& t ) {
    ranges::begin (t); // equality-preserving for forward iterators
    ranges::end (t);
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
-  [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).
[edit] Notes
A typical range class only needs to provide two functions:
-  A member function begin()whose return type modelsinput_or_output_iterator.
-  A member function end()whose return type modelssentinel_for<It>, whereItis the return type ofbegin().
Alternatively, they can be non-member functions, to be found by argument-dependent lookup.
[edit] Example
Run this code
#include <ranges> // A minimum range struct SimpleRange { int* begin(); int* end(); }; static_assert(std::ranges::range<SimpleRange>); // Not a range: no begin/end struct NotRange { int t {}; }; static_assert(!std::ranges::range<NotRange>); // Not a range: begin does not return an input_or_output_iterator struct NotRange2 { void* begin(); int* end(); }; static_assert(!std::ranges::range<NotRange2>); int main() {}
[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 |