GURU of The Week Terms 18: Iterators (Iterative)

zhaozj2021-02-08  344

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 e;

Copy (istream_iterator (cin),

iStream_iterator (),

Back_INSERTER (E));

Vector :: item first =

Find (E.BEGIN (), E.End (), "01/01/95");

Vector :: item last =

Find (E.BEGIN (), E.End (), "12/31/95");

* Last = "12/30/95";

Copy (First, Last, Ostream_iterator (Cout, "/ N"));

E.Nsert (--e.end (), todaysdate ());

Copy (First, Last, Ostream_iterator (Cout, "/ N"));

}

[answer]

The following program contains at least 4 issues related to Iterator. How many can you find?

INT main (int, char * []) ​​{

Vector e;

Copy (istream_iterator (cin),

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 makes it read from CIN STREAM. The COPY algorithm only places the read Date information into the vector.

Vector :: item first =

Find (E.BEGIN (), E.End (), "01/01/95");

Vector :: item last =

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 (cout, "/ n"));

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 (cout, "/ n"));

}

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)

转载请注明原文地址:https://www.9cbs.com/read-408.html

New Post(0)