You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/standard-library/ranges.md
+11-11Lines changed: 11 additions & 11 deletions
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,7 @@
1
1
---
2
2
title: "<ranges>"
3
3
description: "Overview of the Standard Template Library (STL) ranges library"
4
-
ms.date: "04/13/2021"
4
+
ms.date: "04/14/2021"
5
5
f1_keywords: ["<ranges>"]
6
6
helpviewer_keywords: ["ranges"]
7
7
---
@@ -16,8 +16,6 @@ With ranges, you can simply call `std::ranges::sort(myVector);` which is treated
16
16
17
17
Code that is easier to write and more readable is great, but the benefits of ranges go further than that. They also make it easier to filter and transform collections of data in part by allowing you to compose STL algorithms more easily.
18
18
19
-
Because ranges don't own elements like a container does, they're lightweight. The time it takes to copy, move, or assign a range is constant no matter how many elements it points to.
20
-
21
19
## A ranges example
22
20
23
21
Before ranges, if you wanted to transform only the elements of a collection that meet a certain criteria, you'd need to introduce an intermediate step to hold the results between operations. For example, let's say you want to build a vector of squares from only the elements in another vector that are divisible by 3. You'd write something like:
@@ -50,9 +48,7 @@ The result, `output`, is itself a type of range called a view, which is discusse
50
48
51
49
## Views
52
50
53
-
A view is essentially a range that takes another range and transforms how its elements are accessed. How the elements appear depends on the algorithm or operation that you specify. The underlying range is unchanged. In the earlier example, one view took a range and returned a view of only the elements that were divisible by three.
54
-
55
-
A view is lightweight. Like a range, it doesn't own the elements. The time it takes to copy, move, or assign a view is constant, no matter the number of elements it points to.
51
+
A view is a range which can be default constructed, moved, and possibly copied, with the added requirement that all view operations (default construction, move construction/assignment, copy construction/assignment (if present), destruction, begin and end) happen in constant time regardless of the number of elements in the view. How the elements appear depends on the algorithm or operation that you specify for the view. The underlying range is unchanged. In the earlier example, one view took a range and returned a view of only the elements that were divisible by three.
56
52
57
53
Views are composable. In the example above, the view of vector elements that are divisible by three is combined with the view that squares those elements.
58
54
@@ -85,13 +81,13 @@ int main()
85
81
86
82
A view adaptor produces a view over a range. The range being viewed remains unchanged. A view doesn't own any elements. It allows you to iterate over the underlying range using customized behavior that you specify.
87
83
88
-
In the example above, the first view acts like an iterator that only provides the elements of `input` that are divisible by three. The other view acts like an iterator that takes the elements divisible by three, and provides the element's square.
84
+
In the example above, the first view provides the elements of `input` that are divisible by three. The other view takes the elements divisible by three, and provides the element's square.
89
85
90
86
The `<ranges>` library provides many kinds of view adaptors. Besides the filter and transform views, there are views that take or skip the first N elements of a range, reverse the order of a range, join ranges, skip elements of a range until a condition is met, transform the elements of a range, and more.
91
87
92
88
## Range adaptors
93
89
94
-
A range adaptor produces a new range from an existing range. The new range uses customized behavior specified by the range adaptor to provide the elements. For example, a range adaptor might take a range and produce a new one that presents the elements from the original range in reverse order. Views, discussed earlier, are a common kind of range adaptor.
90
+
A range adaptor produces a new range from an existing range and transforms how its elements are accessed. For example, a range adaptor might take a range and produce a new one that presents the elements from the original range in reverse order. Views, discussed earlier, are a common kind of range adaptor.
95
91
96
92
Range adaptors produce lazily evaluated ranges. That is, you don't incur the cost of transforming every element in the range--only the ones that you access, and at the time that you access them.
97
93
@@ -103,13 +99,15 @@ Range adaptors can be chained or composed--which is where the power and flexibil
103
99
104
100
Range algorithms have been created that take a range argument. For example, `std::ranges::sort(myVector);`
105
101
106
-
The range algorithms are lazy, meaning that they operate on the range only when an element is accessed. They can work directly on a container, and can be easily chained together.
102
+
The range algorithms are almost identical to the corresponding iterator-pair algorithms in the `std` namespace, except that they have concept-enforced constraints and accept range arguments or more general iterator-sentinel argument pairs. They can work directly on a container, and can be easily chained together.
107
103
108
104
## Types of ranges
109
105
110
-
What you can do with a range depends on the underlying iterator type of the range. There are different kinds of ranges, called refinements. The different kinds of ranges are codified as C++ 20 concepts. This table lists various range concepts, along with the type of container they can be applied to:
106
+
What you can do with a range depends on the underlying iterator type of the range. Range concepts are refinements of the `range` concept. In C++ 20, to say that concept X refines concept Y means that everything that satisfies Y also satisfies X--though not necessarily the other way around. For example, car, bus, and truck all refine vehicle.
107
+
108
+
The range concepts mirror the hierarchy of iterator categories. This table lists various range concepts, along with the type of container they can be applied to:
111
109
112
-
| Range refinement| Description | Supported containers |
110
+
| Range concept| Description | Supported containers |
113
111
|--|--|--|
114
112
|`std::ranges::input_range`| Can iterate from beginning to end at least once |
0 commit comments