Summary of failures of the C ++ iterator

Source: Internet
Author: User

First, for vector, adding and deleting operations may invalidate some or all of the iterators of the container. Why does the iterator fail? Vector elements are stored sequentially in the memory. Imagine: if there are already 10 elements in the current container, we need to add another element to the container, however, there is no free space behind the 10 elements in the memory, and the elements of the vector must be stored sequentially while accessing the index. Therefore, we cannot find a place in the memory to store this element. Therefore, the vector must re-allocate the bucket to store the original elements and newly added elements: the elements stored in the old bucket are copied to the new bucket, and new elements are inserted, finally, cancel the old bucket. In this case, all iterators of the vector container will become invalid. We can see that the above-mentioned method of allocating and revoking memory space achieves the self-growth of vector, and the efficiency is extremely low. To enable the vector container to implement fast memory allocation, the actually allocated container will have more space than the space currently required. The vector container reserves these additional storage areas to store newly added elements, instead of allocating a new bucket each time. You can see this mechanism from the implementation of capacity and reserve in vector. Difference between capacity and size: size indicates the number of elements currently owned by the container, while capacity indicates the total number of elements that the container can store before it has to allocate a new bucket.

Failure of vector iterator:

1. When an element is inserted (push_back), The iterator returned by the end operation is definitely invalid.

2. When an element is inserted (push_back), the return value of capacity is different from that before the element is inserted. Then, the entire container needs to be reloaded, And the iterator returned by the begin and end operations will become invalid.
3. After the delete operation (erase, pop_back) is performed, all the iterators pointing to the delete vertex are invalid. All the iterators pointing to the elements behind the delete vertex are also invalid.
Deque iterator failure:
1. inserting elements at the front or end of the deque container does not invalidate any iterator.
2. Deleting an element at its header or tail will only invalidate the iterator pointing to the deleted element.
3. The insert and delete operations at any other location of the deque container will invalidate all iterators pointing to the container element.

Failure of List/set/map iterator:

The iterator pointing to the deleted node fails to be deleted.

List IntList;
List : Iterator it = intList. begin ();
While (it! = IntList. end ())
{
It = intList. erase (it );
......
}

Summary of various container features

(1) vector

Internal data structure: array.

Each element is randomly accessed. The time required is a constant.
The time required to add or delete an element at the end is irrelevant to the number of elements. The time required to add or delete an element at the beginning or in the middle changes linearly with the number of elements.
You can dynamically add or remove elements and manage the memory automatically. However, you can use the reserve () member function to manage the memory.
The iterator of the vector will become invalid when the memory is re-allocated (the elements it points to are no longer the same before and after the operation ). When more than capacity ()-size () elements are inserted into the vector, the memory will be re-allocated and all iterators will become invalid; otherwise, the iterator pointing to any element after the current element fails. When an element is deleted, the iterator pointing to any element after the element is deleted becomes invalid.

(2) deque

Internal data structure: array.
Each element is randomly accessed. The time required is a constant.
The time required to add an element at the beginning and end is irrelevant to the number of elements. The time required to add or delete an element in the middle changes linearly with the number of elements.
Elements can be dynamically added or removed, and memory management is completed automatically. member functions used for memory management are not provided.
Adding any element will invalidate the deque iterator. Deleting an element in the middle of deque will invalidate the iterator. When a deque header or tail deletes an element, only the iterator pointing to the element fails.

(3) list

Internal data structure: Bidirectional Ring linked list.
You cannot randomly access an element.
Bidirectional traversal is supported.
The time required to add or delete an element at the beginning, end, or in the middle is constant.
You can dynamically add or remove elements and manage the memory automatically.
Adding any element will not invalidate the iterator. When an element is deleted, other iterators will not expire except the iterator pointing to the currently deleted element.
(4) slist

Internal data structure: one-way linked list.
It cannot be traversed in two directions. It can only be traversed from front to back.
Other features are similar to list.

(5) stack

Adapter, which can convert any type of sequence container into a stack. Generally, deque is used as the supported sequence container.
The element can only be post-in, first-out (LIFO ).
The entire stack cannot be traversed.

(6) queue

It can convert any type of sequence container into a queue. Generally, deque is used as the supported sequence container.
The element can only be FIFO ).
The entire queue cannot be traversed.

(7) priority_queue

It can convert any type of sequence container into a priority queue. Generally, vector is used as the underlying storage mode.
Only the first element can be accessed, and the whole priority_queue cannot be traversed.
The first element is always the element with the highest priority.

(8) set

The key is unique.
Elements are arranged in ascending order by default.
If the element to which the iterator points is deleted, the iterator becomes invalid. Any other operations to add or delete elements will not invalidate the iterator.

(9) multiset

The key may not be unique.

Other features are the same as those of set.

(10) map

The key is unique.
The elements are sorted in ascending order by default.
If the element to which the iterator points is deleted, the iterator becomes invalid. Any other operations to add or delete elements will not invalidate the iterator.

(11) multimap

The key may not be unique.
Other features are the same as those of map.

1. Container iterator type
Each container type defines its own iterator type, such as vector:
Vector: iterator iter;
This statement defines a variable named iter. Its data type is the iterator type defined by vector. Each standard library container type defines a member named iterator. The iterator here has the same meaning as the actual type of the iterator.
2. begin and end operations
Each container defines a function named begin and end for returning the iterator. If the container contains elements, the iterator returned by begin points to the first element:
Vector: iterator iter = ivec. begin ();
The preceding statement initializes iter to the value returned by the vector operation named begin. Assume that the vector is not empty. After initialization, iter indicates that the element is ivec [0].
The iterator returned by the end operation points to the "next to the end element" of the vector ". It is usually called the off-the-end iterator, indicating that it points to a nonexistent element. If the vector is empty, the iterator returned by begin 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. On the contrary, it only acts as a sentinel, indicating that all elements in the vector have been processed.
3. Auto-increment and reference operations of the vector iterator
The iterator type defines some operations to get the elements pointed to by the iterator, and allows the programmer to move the iterator from one element to another.
For the iterator type, you can use the unreferenced operator (* operator) to access the r element pointed to by the iterator:
* Iter = 0;
The unreference operator returns the element currently pointed to by the iterator. Assuming that iter points to the first element of the vector object ivec, * iter and ivec [0] point to the same element. The result of the preceding statement is to assign the value of this element to 0.
The iterator uses the auto-increment operator to move the iterator forward to the next element in the container. Logically, the auto-increment operation of the iterator is similar to that of an int object. For an int object, the operation result is to add the int value to 1, while for an iterator object, the iterator in the container is to "move forward a position ". Therefore, if iter points to the first element, ++ iter points to the second element.
Since the iterator returned by the end operation does not point to any element, it cannot be unreferenced or auto-increment.
4. other operations of the iterator
Another pair of operations that can be executed on the iterator is comparison: Use = or! = Operator to compare two iterators. If the two iterator objects point to the same element, they are equal. Otherwise, they are not equal.
5. program example of the iterator Application
Assume that a vector-type ivec variable has been declared. To reset all its element values to 0, you can perform the subscript operation:
// Reset all the elements in ivec to 0
For (vector: size_type ix = 0; ix! = Ivec. size (); ++ ix)
Ivec [ix] = 0;
The above program uses the for loop to traverse the ivec elements. The for loop defines an index ix, and each iteration of ix increases by 1. For Loop body, assign each element of ivec to 0

Summary:
1. For the deletion of the associated container (map, list, set) element, the insert operation will cause the iterator pointing to this element to become invalid, and the iterator of other elements will not be affected.
2. Deletion and insertion of the vector element will invalidate the iterator pointing to the element and the subsequent element.

About iterator
(1) features and operations
L the basic features of the iterator include:
Detaching -- supports the dereference operation so that you can access the value it references. That is, if p is an iterator, * p and p-> should be defined (like pointers );
Assign value -- you can assign an iterator to another iterator. That is, if p and q are both iterators, the expression p = q should be defined;
Comparison -- compare an iterator with another iterator. That is, if both p and q are iterators, the expressions p = q and p! = Q;
Traversal -- The iterator can be used to traverse elements in the container, which can be implemented by defining ++ p and p ++ operations for the iterator p.
Iterator operations include:
Read-indirectly reference the element value in the container by unreferencing *, for example, x = * p;
Write -- assign values to elements in the container by removing the reference *, for example, * p = x;
Access-reference elements and their members in the container by subscript and pointing, such as p [2] and p-> m
Iteration-uses the increment and decrement operations (++ and --, + and-, + =, and-=) to traverse, roam, and skip the container, for example, p ++, -- p, p + 5, p-= 8
Comparison -- use the comparison operator (= ,! =, <,>, <=,> =) To compare whether two iterators are equal or who is big or small, such as if (p <q )......; , Wihle (p! = C. end ())......;
(2) Classification
According to the operations supported by the iterator, the following five iterators are defined in STL:
L input iterator (input iterator) -- used to read information in the container, but cannot be modified.
The input iterator iter reads the value of the element pointed to by the container by unreferencing (* iter;
To allow the input iterator to access the values of all elements in the container, it must support the (prefix/suffix format) ++ operator;
The input iterator does not guarantee that the sequence remains unchanged when the container is traversed for the second time; nor does it ensure that the previously pointed value remains unchanged after it increments. That is, any algorithm based on the input iterator should be single-pass, independent of the previous time value or the previous value in this traversal.
It can be seen that the input iterator is a one-way read-only iterator that can increase but cannot decrease, and can only be read or written. It is applicable to single-pass read-only algorithms.
L output iterator-used to transmit information to the container (modify the value of elements in the container), but cannot be read. For example, a display can only write devices that cannot be read, and can be expressed by an output container. It also supports unreferencing and ++ operations. Therefore, the output iterator is applicable to single-pass write-only algorithms.
L forward iterator (forward iterator)-only the ++ operator can be used to traverse containers in one way (not --). Like the I/O iterator, the forward iterator also supports removing references and ++ operations. Unlike the I/O iterator, the forward iterator is multi-pass ). That is, it always traverses the container in the same order, and after the iterator increments, it can still get the same value by releasing the retained iterator reference. In addition, the forward iterator can be read-write or read-only.
L bidirectional iterator-you can use ++ and -- operators to traverse containers in two directions. Like the forward iterator, other sdks also support unreferencing, multi-pass, read-write, and read-only.
L random access iterator-a bidirectional iterator that can directly access any element in the container.
It can be seen that these five iterators form a hierarchical structure: I/O iterators (both can be ++ traversed, but the former read-only and the latter write only) basic: The forward iterator can read and write but can only be ++ traversed. The bidirectional iterator can also read and write, but can ++/-- bidirectional traversal. the random iterator can also be used in addition to bidirectional traversal. random Access.
(3) pointer and iterator
Since the iterator is a generalized pointer, is the pointer itself an iterator? In fact, pointers meet the requirements of all iterators. Therefore, pointers are an iterator.
The iterator is the interface of the generic algorithm, and the pointer is the iterator. Therefore, various STL algorithms can also use pointers to operate non-standard containers (such as arrays. That is, the STL algorithm can be used as a regular array by using pointers as an iterator.
For example, the sorting function sort:
Sort (Ran first, Ran last); // Ran indicates Random Access to the iterator
For container c:
Sort (c. begin (), c. end ());
You can change array a to: (const int SIZE = 100; float a [SIZE];)
Sort (a, a + SIZE );
Another example is copy function:
Copy (In first, In last, Out res); // In and Out indicate the input and output iterators respectively.
For container c Optional values: (ostream_iterator) Out_iter (cout );)
Copy (c. begin (), c. end (), out_iter );
You can change array a to: (const int SIZE = 100; float a [SIZE];)
Copy (a, a + SIZE, c. begin ());

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.