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/iterator.md
+17-1Lines changed: 17 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -19,7 +19,19 @@ There are three classes of insert iterator adaptors: front, back, and general. T
19
19
20
20
## Remarks
21
21
22
-
Iterators are a generalization of pointers that allow a C++ program to work with different data structures in a uniform way. Instead of operating on specific data types, algorithms operate on a range specified by a type of iterator. Any data structure that satisfies the requirements of the iterator can be operated upon by the algorithm. There are five types or categories of iterators:
22
+
Iterators are a generalization of pointers that allow a C++ program to work with different data structures in a uniform way. Instead of operating on specific data types, algorithms operate on a range specified by a type of iterator. Any data structure that satisfies the requirements of the iterator can be operated upon by the algorithm. In C++20, there are x categories of iterators:
| Bidirectional | Forward and backward | Read/Write |`list`, `set`, `multiset`, `map`, and `multimap`. |
32
+
| Random access | Any order | Read/Write |`vector`, `deque`, `string`, and `array`. |
33
+
34
+
Until In C++17, there are five types or categories of iterators:
23
35
24
36
| Kind | Direction | Read/Write| Example types|
25
37
|---|---|---|---|
@@ -74,6 +86,10 @@ Visual Studio has added extensions to C++ Standard Library iterators to support
74
86
|[`operator+`](../standard-library/iterator-operators.md#op_add)|Adds an offset to an iterator and returns the new `reverse_iterator` addressing the inserted element at the new offset position.|
75
87
|[`operator-`](../standard-library/iterator-operators.md#operator-)|Subtracts one iterator from another and returns the difference.|
Range adaptors create a *view* (one of the [View classes](view-classes.md) in the `std::views` namespace) from a range. We recommend that you use an adaptor in `std::ranges::views` instead of creating the view types directly. The adaptors are the intended way to access views. They're easier to use, and in some cases more efficient, than creating instances of the view types directly.
10
+
Range adaptors create a *view* (one of the [View classes](view-classes.md) in the `std::views` namespace) from a range. We recommend that you use an adaptor to create views instead of creating the view types directly. The adaptors are the intended way to access views. They're easier to use, and in some cases more efficient, than creating instances of the view types directly.
11
11
12
12
A view is a lightweight object that refers to elements from a range. A view can:
13
13
@@ -48,9 +48,9 @@ The first range adaptor, [`filter`](filter-view-class.md), provides a view that
48
48
49
49
When a range adaptor produces a view, it doesn't incur the cost of transforming every element in the range to produce that view. The cost to process an element in the view is paid only when you access that element.
50
50
51
-
Creating a view only prepares to do work in the future. In the previous example, creating the view doesn't result in finding all the elements divisible by three. It also doesn't square the elements that it finds. That work happens only when you access an element in the view.
51
+
Creating a view is preparation to do work in the future. In the previous example, creating the view doesn't result in finding all the elements divisible by three or squaring those elements. Work happens only when you access an element in the view.
52
52
53
-
Elements of a view are usually the actual elements of the range that are used to create the view. The view usually doesn't own the elements([`owning_view`](owning-view-class.md) is an exception); it just refers to them. Changing an element changes that element in the range that the view was created from. The following example shows this behavior:
53
+
Elements of a view are usually the actual elements of the range used to create the view. The view usually doesn't own the elements; it just refers to them. Although ([`owning_view`](owning-view-class.md) is an exception. Changing an element changes that element in the range that the view was created from. The following example shows this behavior:
Concepts are a C++20 language feature that constrain template parameters at compile time. They help prevent incorrect template instantiation, convey template argument requirements in a readable form, and provide more succinct template related compiler errors.
10
+
Concepts are a C++20 language feature that constrain template parameters at compile time. They help prevent incorrect template instantiation, specify template argument requirements in a readable form, and provide more succinct template related compiler errors.
11
11
12
12
Consider the following example, which defines a concept to prevent instantiating a template with a type that doesn't support division:
13
13
@@ -50,27 +50,40 @@ int main()
50
50
51
51
When you pass the compiler switch `/diagnostics:caret` to Visual Studio 2022 version 17.4p4 or later, the error that concept `dividable<char*>` evaluated to false will point directly to the expression requirement `(a / b)` that failed.
52
52
53
-
The following concepts are defined in `std::ranges` and are declared in the `<ranges>` header file. They're used in the declarations of [range adaptors](range-adaptors.md), [views](view-classes.md), and so on.
53
+
Range concepts are defined in the `std::ranges` namespace as declared in the `<ranges>` header file. They're used in the declarations of [range adaptors](range-adaptors.md), [views](view-classes.md), and so on.
54
+
55
+
There are six categories of ranges. They are related to the categories of iterators listed in [`<iterator> concepts](iterator-concepts.md).
56
+
57
+
In order of increasing capability, the categories are:
58
+
59
+
| Range concept | Description |
60
+
|--|--|
61
+
|[`output_range`](#output_range)| Specifies a range that you can write to. JTW It supports [output_iterator](iterators.md# JTW) Repeat this pattern for the entries below. |
62
+
|[`input_range`](#input_range)| Specifies a range that you can read from at least once. |
63
+
|[`forward_range`](#forward_range)| Specifies a range that can read (and possibly write) multiple times. |
64
+
|[`bidirectional_range`](#bidirectional_range)| Specifies a range that can read and write both forwards and backwards. |
65
+
|[`random_access_range`](#random_access_range)| Specifies a range that can read and write by index. |
66
+
|[`contiguous_range`](#contiguous_range)| Specifies a range whose elements are sequential in memory and can be accessed using pointer arithmetic. |
67
+
68
+
In the preceding table, concepts are listed in order of increasing capability. A range that meets the requirements of a concept for a category generally meets the requirements of all concepts in the categories that precede it. For example, a `random_access_range` has the capability of a `bidirectional_range`, `forward_range`, `input_range`, and `output_range`. However, an exception is `input_range` which doesn't have the capability of an `output_range` because it can't be written to.
69
+
70
+
Other range concepts include:
54
71
55
72
| Range concept | Description |
56
73
|--|--|
57
-
|[`range`](#range)<sup>C++20</sup> | A type that provides an iterator and a sentinel. |
58
-
|[`bidirectional_range`](#bidirectional_range)<sup>C++20</sup> | Supports reading and writing forwards and backwards. |
59
-
|[`borrowed_range`](#borrowed_range)<sup>C++20</sup> | The lifetime of the type's iterators aren't tied to the object's lifetime. |
60
-
|[`common_range`](#common_range)<sup>C++20</sup> | The type of the iterator and the type of the sentinel are the same. |
61
-
|[`contiguous_range`](#contiguous_range)<sup>C++20</sup> | The elements are sequential in memory and can be accessed by using pointer arithmetic. |
62
-
|[`forward_range`](#forward_range)<sup>C++20</sup> | Supports reading (and possibly writing) a range multiple times. |
63
-
|[`input_range`](#input_range)<sup>C++20</sup> | Supports reading at least once. |
|[`random_access_range`](#random_access_range)<sup>C++20</sup> | Supports reading and writing by index. |
74
+
|[`range`](#range)<sup>C++20</sup> | Specifies a type that provides an iterator and a sentinel. |
75
+
|[`borrowed_range`](#borrowed_range)<sup>C++20</sup> | Specifies that the lifetime of the range's iterators aren't tied to the range's lifetime. |
76
+
|[`common_range`](#common_range)<sup>C++20</sup> | Specifies that the type of the range's iterator and the type of the range's sentinel are the same. |
66
77
|[`Simple_View`](#simple_view)<sup>C++20</sup> | Not an official concept defined as part of the standard library, but used as a helper concept on some interfaces. |
67
-
|[`sized_range`](#sized_range)<sup>C++20</sup> | Provides the number of elements in a range efficiently. |
68
-
|[`view`](#view)<sup>C++20</sup> | Has efficient (constant time) move construction, assignment, and destruction. |
69
-
|[`viewable_range`](#viewable_range)<sup>C++20</sup> | A type that either is a view or can be converted to one. |
78
+
|[`sized_range`](#sized_range)<sup>C++20</sup> | Specifies a range that can provide the number of elements in a range efficiently. |
79
+
|[`view`](#view)<sup>C++20</sup> | Specifies a type that has efficient (constant time) move construction, assignment, and destruction. |
80
+
|[`viewable_range`](#viewable_range)<sup>C++20</sup> | Specifies a type that either is a view or can be converted to one. |
81
+
82
+
For a list of JTW
70
83
71
84
## `bidirectional_range`
72
85
73
-
A `bidirectional_range` supports reading and writing forwards and backwards.
86
+
A `bidirectional_range` supports reading and writing the range forwards and backwards.
74
87
75
88
```cpp
76
89
template<classT>
@@ -178,7 +191,7 @@ true
178
191
179
192
## `forward_range`
180
193
181
-
A `forward_range` supports reading (and possibly writing) a `range` multiple times.
194
+
A `forward_range` supports reading (and possibly writing) the range multiple times.
182
195
183
196
```cpp
184
197
template<classT>
@@ -196,7 +209,7 @@ A `forward_iterator` can iterate over a range multiple times.
196
209
197
210
## `input_range`
198
211
199
-
An `input_range` is a `range` that can be read from at least once.
212
+
An `input_range` is a range that can be read from at least once.
200
213
201
214
```cpp
202
215
template<classT>
@@ -219,7 +232,7 @@ When a type meets the requirements of `input_range`:
219
232
220
233
## `output_range`
221
234
222
-
An `output_range` is a `range` that you can write to.
235
+
An `output_range` is a range that you can write to.
The meaning of `output_iterator<iterator_t<R>, T>` is that the type provides an iterator that can write values of type `T` to a `range` of type `R`.
252
+
The meaning of `output_iterator<iterator_t<R>, T>` is that the type provides an iterator that can write values of type `T` to a range of type `R`.
240
253
241
254
## `random_access_range`
242
255
243
-
A `random_access_range` can read or write a `range` by index.
256
+
A `random_access_range` can read or write a range by index.
244
257
245
258
```cpp
246
259
template<class T>
@@ -327,7 +340,7 @@ The type to test to see if it's a `sized_range`.
327
340
328
341
The requirements of a `sized_range` are that calling `ranges::size` on it:
329
342
330
-
- Doesn't modify the `range`.
343
+
- Doesn't modify the range.
331
344
- Returns the number of elements in amortized constant time. Amortized constant time doesn't mean O(1), but that the average cost over a series of calls, even in the worst case, is O(n) rather than O(n^2) or worse.
332
345
333
346
Some examples of a `sized_range` are `std::list` and `std::vector`.
@@ -366,7 +379,7 @@ The type to test to see if it's a view.
366
379
367
380
### Remarks
368
381
369
-
The essential requirement that makes a view composable is that it's cheap to move/copy. This is because the view is moved/copied when it's composed with another view. It must be a movable `range`.
382
+
The essential requirement that makes a view composable is that it's cheap to move/copy. This is because the view is moved/copied when it's composed with another view. It must be a movable range.
370
383
371
384
`ranges::enable_view<T>` is a trait used to claim conformance to the semantic requirements of the `view` concept. A type can opt in by:
372
385
- publicly and unambiguously deriving from a specialization of `ranges::view_interface`
0 commit comments