Introduction to C + + iterator basics
Iterators provide access to objects in a container, and define the scope of the objects in the container. An iterator is like a pointer. In fact, C + + pointers are also an iterator. However, iterators are not just pointers, so you can't think they must have address values. An array index, for example, can also be thought of as an iterator.
In addition to using subscripts to access the elements of a vector object, the standard library provides another way to access elements: using Iterators (iterator). An iterator is a data type that examines the elements inside a container and traverses the elements.
The standard library defines an iterator type for each of the standard containers, including vectors. Iterator types provide a more generalized approach than subscript operations: All standard library containers define the appropriate iterator types, and only a handful of containers support subscript operations. Because iterators are applicable to all containers, modern C + + programs tend to use iterators rather than subscript operations to access container elements, even for vector types that support subscript operations.
Iterator type of container
Each container type defines its own iterator type, such as vector:
Vector<int>::iterator ITER;
This character statement defines a variable named ITER whose data type is the iterator type defined by vector<int>. Each standard library container type defines a member named iterator, where the iterator has the same meaning as the actual iterator type.
Terminology: iterators and iterator types
The first time a programmer encounters a term about an iterator may be confusing, one reason being that the same term iterator often represents two different things. In general, it refers to the concept of an iterator, while in particular it refers to the specific iterator type defined by the container, such as vector<int>.
It is important to understand that there are many types that are used as iterators, and these types are conceptually relevant. If a type supports a set of deterministic actions that can be used to traverse elements within a container and access the values of those elements, we call this type an iterator.
Each container class defines its own iterator type, which is used to access the elements within the container. In other words, each container defines a type named iterator, and this type supports various operations (conceptual) iterators.
Vector<int>::iterator iter =ivec.begin ();
begin and end operations
Each container defines a pair of functions named Begin and end, which are used to return iterators. If there are elements in the container, the iterator returned by begin points to the first element:
Vector<int>::iterator iter =ivec.begin ();
The above statement initializes ITER to the value returned by the name of the vector operation. Assuming that the vector is not empty, after initialization, ITER means that the element is ivec[0].
The iterator returned by the end operation points to the next "end element of the vector". "End iterator Exceeded" (off-the-enditerator). Indicates that it points to an element that does not exist. If the vector is empty, begin returns an iterator that is the same as the iterator returned by end.
The iterator returned by the end operation does not point to any actual element in the vector, but instead it acts as a Sentinel (Sentinel), indicating that we have processed all the elements in the vector.
Self-increment and dereference operations of Vector iterators
The iterator type defines actions to get the element that the iterator points to, and allows the programmer to move the iterator from one element to another.
An iterator type can use the dereference operator (dereferenceoperator) (*) to access the element that the iterator points to:
*iter = 0;
The dereference operator returns the element to which the iterator is currently pointing. Assuming that ITER points to the first element of the vector object Ivec, then *iter and ivec[0] are pointing to the same element. The effect of the above statement is to assign the value of this element to 0.
The iterator uses the increment operator to move the iterator forward to point to the next element in the container. Logically, the self-increment of an iterator is similar to the self-increment operation of an int object. For an int object, the result of the operation is to "add 1" to the int value, while the iterator object is to "move forward one position" in the container. Therefore, if ITER points to the first element, then ++iter points to the second element.
Because the iterator returned by the end operation does not point to any element, it cannot be dereferenced or self-increment.
Additional Actions for iterators
Another pair of actions that can be performed on iterators is comparison: compare two iterators with the = = or! = operator, and if the two iterator objects point to the same element, they are equal, otherwise they are not equal.
Examples of programs that iterators apply
Assuming that you have declared a vector<int>-type Ivec variable, to reset all its element values to 0, you can use the subscript operation to complete:
Reset all the elements in Ivec to 0 for (vector<int>::size_type ix = 0; ix!= ivec.size (); ++ix) Ivec[ix] = 0;
The above program iterates through the elements of the Ivec with a For loop, and the For Loop defines an index IX, which will increment by 1 for each iteration of the loop. The For loop body assigns each element of the Ivec a value of 0.
A more typical practice is to use iterators to write loops:
Equivalent loop using iterators to resetall the elements of Ivec to 0for (vector<int>::iterator iter = Ivec.begin ( ); ITER! = Ivec.end (); ++iter) *iter = 0;
<span style= "font-family:arial, Helvetica, Sans-serif;" >//set element to which ITER refers to 0</span>
The For loop first defines ITER and initializes it to the first element that points to Ivec. The condition of the For loop tests whether ITER is not equal to the iterator returned by the end operation. Each iteration of ITER increases by 1, and the effect of this for loop is to process each element in the vector sequentially, starting with the first element of Ivec. Finally, ITER will point to the last element in the Ivec, and after the last element is processed, ITER increases by 1, which is equal to the return value of the end operation, in which case the loop terminates.
The statement in the For loop body accesses the value of the current element with the dereference operator. As with the subscript operator, the return value of the dereference operator is an lvalue, so it can be assigned to change its value. The effect of these loops is to assign all the elements in the Ivec to a value of 0.
Through the detailed analysis of the code above, it can be seen that this program with the subscript operator version achieves the same effect: starting with the first element of the vector, each element in the vector is set to 0.
The example program given in this section, if the vector is empty, the program is safe. If Ivec is empty, the iterator returned by begin does not point to any element--it cannot point to any element because there is no element. In this case, the iterator returned from the begin operation is the same as the value of the iterator returned from the end operation, so the test condition in the For statement immediately fails.
Const_iterator
The previous program uses Vector::iterator to change the value of the elements in the vector. Each container type also defines a type named Const_iterator, which can only be used to read elements within a container, but cannot change its value.
When we dereference an ordinary iterator type, we get the non-const (section 2.5) of an element. And if we dereference the const_iterator type, we can get a reference to the Const object (Section 2.4), which, like any constant, cannot be overridden.
For example, if text is a vector<string> type, the programmer wants to traverse it and output each element so that it can write a program like this:
Use const_iterator because we won ' tchange the Elements for (Vector<string>::const_iteratoriter = Text.begin (); ITER! = Text.end (); ++iter) cout << *iter << Endl;//Printeach element in text
This loop is similar to the previous one except that it reads the element value from the iterator instead of assigning it a value. Since this is only necessary to read with an iterator, it does not need to be written, which defines ITER as the const_iterator type. When the const_iterator type is dereferenced, a const value is returned. Do not allow assignment with const_iterator:
for (Vector<string>::const_iteratoriter = Text.begin (); ITER! = Text.end (); + iter) *iter = ""; Error: *iter is const
When using the Const_iterator type, we can get an iterator whose own value can be changed, but cannot be used to change the value of the element it points to. You can self-increment an iterator and use the dereference operator to read a value, but you cannot assign a value to the element.
do not confuse the Const_iterator object with the Const iterator object. when declaring a const iterator, you must initialize the iterator. Once initialized, it is not possible to change its value:
Vector<int> Nums (ten); Nums is nonconst const vector<int>::iterator cit =nums.begin (); *cit = 1; Ok:cit can change it underlying element ++cit;//Error:can ' t change the value of CIT
The Const_iterator object can be used with a const vector or a non-const vector because element values cannot be overwritten. Const iterator This type is almost useless: once it is initialized, it can only be used to overwrite the element it points to, but it cannot point to any other element.
Const Vector<int> Nines (9); Cannot change elements in Nines //error:cit2 could-the element itrefers to and Nines are const Const VE Ctor<int>::iterator cit2 =nines.begin (); Ok:it can ' t change an element value, soit can is used with a const vector<int> vector<int>::const_iter Ator it =nines.begin (); *it = 10; Error: *it is const ++it; Ok:it ' t const so we can change it value //An iterator that cannot write elements vector<int>::cons T_iterator //An iterator whose value cannot change constvector<int>::iterator
Arithmetic operations of iterators
In addition to the increment operator for one element of a move iterator at a time, vector iterators (with few other standard library container iterators) also support other arithmetic operations. These operations are called iterator arithmetic operations (iterator arithmetic), including:
ITER + niter-n
You can add or subtract an integer value from an iterator object. Doing so will result in a new iterator whose position precedes (plus) or after (minus) n elements of the element that ITER refers to. The result after addition or subtraction must point to an element in the vector indicated by ITER, or the latter element at the end of the vector. The type of the added or subtracted value should be the Size_type or difference_type type of the vector (see explanation below).
Iter1-iter2
The expression is used to calculate the distance of two iterator objects, which is the value of the signed type size_type named Difference_type, where Difference_type is the signed type because the subtraction operation can produce negative results. The type can be guaranteed to be large enough to store the distance between any two iterator objects. Both Iter1 and Iter2 must both point to the element in the same vector, or to the next element after the end of the vector.
You can use an iterator arithmetic operation to move an iterator directly to an element, for example, the following statement is positioned directly in the vector intermediate element:
Vector<int>::iterator mid = Vi.begin () +vi.size ()/2;
The code above is used to initialize mid so that it points to the element closest to the middle in VI. This method of directly computing iterators is equivalent to the method of using iterators to get the intermediate elements by element-by-increment operations, but the former is much more efficient.
Any action that alters the length of the vector will invalidate an existing iterator. For example, after calling Push_back, you can no longer trust the value of the iterator that points to the vector.
C + + iterators