std::ranges::range
From cppreference.com
| 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)andranges::end(E)are amortized constant time and do not alter the value ofEin a manner observable to equality-preserving expressions, and - if the type of
ranges::begin(E)modelsforward_iterator,ranges::begin(E)is equality-preserving (in other words, forward iterators support multi-pass algorithms).
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.
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() {}
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 |