Difference between revisions of "cpp/ranges/range"
From cppreference.com
m (in-house fmt.) |
m (→Example: {{source}} => {{example}} to enable online experiments.) |
||
Line 26: | Line 26: | ||
===Example=== | ===Example=== | ||
− | {{ | + | {{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 |
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 |
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
Defined in header <ranges>
|
||
template< class T > concept range = requires( T& 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
-
[
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>
, whereIt
is 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 |