Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/ranges/range"

From cppreference.com
< cpp‎ | ranges
m (in-house fmt.)
m (Example: {{source}} => {{example}} to enable online experiments.)
 
Line 26: Line 26:
  
 
===Example===
 
===Example===
{{source|1=
+
{{example
 +
|code=
 
#include <ranges>
 
#include <ranges>
  
Line 37: Line 38:
 
static_assert(std::ranges::range<SimpleRange>);
 
static_assert(std::ranges::range<SimpleRange>);
  
// not a range: no begin/end
+
// Not a range: no begin/end
 
struct NotRange
 
struct NotRange
 
{
 
{
Line 44: Line 45:
 
static_assert(!std::ranges::range<NotRange>);
 
static_assert(!std::ranges::range<NotRange>);
  
// not a range: begin does not return an input_or_output_iterator
+
// Not a range: begin does not return an input_or_output_iterator
 
struct NotRange2
 
struct NotRange2
 
{
 
{
Line 51: Line 52:
 
};
 
};
 
static_assert(!std::ranges::range<NotRange2>);
 
static_assert(!std::ranges::range<NotRange2>);
 +
 +
int main() {}
 
}}
 
}}
  

Latest revision as of 07:54, 25 July 2024

 
 
Ranges library
Range adaptors
 
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.

Contents

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