Gotw # 18 Iterators
Author: Herb Sutter
Translation: k] [N g of @ rkTM
[Declaration]: This article takes the Guru of The Week column on www.gotw.ca website, and its copyright belongs to the original person. Translator Kingofark translated this article without the consent of the original person. This translation is only for self-study and reference, please read this article, do not reprint, spread this translation; people download this translation content, please delete its backup immediately after reading. Translator Kingofark is not responsible for people who violate the above two principles. This declaration.
Revision 1.0
GURU of The Week Terms 18: Iterators (Iterative)
Difficulty: 7/10
(Every item using standard libraries must pay attention to these common or rare Iterator errors. How many errors can you find?)
[problem]
The following program contains at least 4 issues related to Iterator. How many can you find?
INT main (int, char * []) {
Vector
Copy (istream_iterator
iStream_iterator
Back_INSERTER (E));
Vector
Find (E.BEGIN (), E.End (), "01/01/95");
Vector
Find (E.BEGIN (), E.End (), "12/31/95");
* Last = "12/30/95";
Copy (First, Last, Ostream_iterator
E.Nsert (--e.end (), todaysdate ());
Copy (First, Last, Ostream_iterator
}
[answer]
The following program contains at least 4 issues related to Iterator. How many can you find?
INT main (int, char * []) {
Vector
Copy (istream_iterator
iStream_iterator
Back_INSERTER (E));
It is still not far from the program so far. The writer of the Date Class provides an extractor function in Signature Operator >> (ISTREAM &, DATE &), iStream_iterator
Vector
Find (E.BEGIN (), E.End (), "01/01/95");
Vector
Find (E.BEGIN (), E.End (), "12/31/95");
* Last = "12/30/95";
Error: This may be illegal, because 'Last' may be E.End (), and it is a Dereferenceable Iterator that cannot be implemented. If the specified value is not found, the Find algorithm returns its second quotes (ie, the last Iterator). Here, if "12/31/95" is not in E, 'Last' will be equal to E.End (), which points to the next position in the last place in Container, is not a valid Iterator.
COPY (First, Last,
Ostream_iterator
Error: This may be illegal, because 'first' may be behind 'Last'.
If "01/01/95" can not be found in E, "12/31/95" can be found, then Iterator 'Last' will point to the "Iterator 'First'" referred to in the collection (here is here. The location of the end after the end) "The Date object equal to" 12/31/95 "). However, the COPY algorithm requires 'first' must point to the position of 'Last' in the same episode - which is both, [first, last] must be a valid range.
Unless you use a standard library that supports such checks, the above situation will result in a COPY algorithm to generate Core Dump after execution, and it is difficult to diagnose this.
E.Nsert (--e.end (), todaysdate ());
Error: Expression "--e.end ()" is illegal.
It is also very simple to be a little in the case. It is only a Date *, which does not allow you to modify the interim targets of the built-in. For example, the following usual code is also illegal:
Date * f (); // This function returns DATE *
P = --f (); // error; "F () - 1" is feasible
Fortunately, you can write the following (slightly) correct code and do not lose any efficiency:
E.Nsert (e.end () - 1, todaysdate ());
Error: In fact, there is still other errors - if e is empty, then e.end () - 1 is not a valid Iterator.
COPY (First, Last,
Ostream_iterator
}
Error: 'first' and 'last' This time it is no longer a valid Iterators.
Vector is growing in the so-called "chunks" so that every time you insert it, the Vector does not have to reassign the buffer. However, the vector is sometimes filling, and the addition of it will cause redistribution. Here, after the insertion operation is completed, the Vector may grow may not grow. If you grow, you will make our existing Iterators fail, so the next copy will lead to a difficult DUE DUMP that is difficult to diagnose.
[summary]
Note the following four main issues when using Iterator:
1. Effective value: Can ITeferenceABLEABLE? For example, "* e.end ()" is always a logical error.
2. Effective survival: Is it still effective when Iterator is used? When we get it, is it invalid if it has been inactive? 3. Effective range: Is a pair of ITERATORS to form a legal range? Is 'first' before 'Last' or equal to 'Last'? Does this do point to Iterator inside the same container?
4. Illegal built-in manipulation. For example, the above "--e.end ()", which attempts to modify a built-in other temporary object (fortunately, the compiler will pay attention to you and discover this problem; and for the Class type Iterators, library The writer often allows such situations to appear for the convenience of grammar).
(Finish)