Ein Iterator ist eine Menge verschiedener Dinge in verschiedenen Sprachen.
Ein offensichtliches Beispiel für etwas "mehr als nur der C# Iterator" ist der C++ Iterator, der im Grunde ein Marker in einer Sequenz ist. Anders als das C# -Äquivalent weiß es nicht, wo die Sequenz beginnt oder endet, es weiß nur, auf welches Element es gerade zeigt, und wie das nächste und vielleicht vorhergehende Element abgerufen wird.
std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5); // create a vector (equivalent to a C# List), and populate it with the numbers 1-5
// create two iterators, pointing to the beginning and end of this vector
std::vector<int>::iterator first = v.begin();
std::vector<int>::iterator last = v.end();
std::copy(first, last, std::ostream_iterator(std::cout)); // copy all elements found between first and last, to the standard output (in the shape of a special output iterator)
oder wenn wir es waren manuell zu durchlaufen, würden wir dies tun:
for (vector<int>::iterator cur = v.begin(); cur != v.end(); ++cur) {
int val = *cur; // get the value pointed to by the iterator
cout << val; // print that value to the standard output
}
Diese Iteratoren sind in der Regel in Paaren (bezeichnet Beginn/Ende einer Sequenz) wie folgt verwendet
Die Wirkung davon ist die gleiche wie die std::copy
Funktion im ersten Beispiel, aber hier können Sie sehen, wie der Iterator tatsächlich verwendet wird, um durch die Sequenz zu bewegen. Das Interessante ist, dass Sie ein Paar von Iteratoren verwenden, so dass Sie anstelle eines Iterators mit einer HasNext() - Funktion "GetCurrent" und "MoveForward" (oder ähnlich) zwei Iteratoren haben und "HasNext" ist grob gesprochen ersetzt durch einen Gleichheitstest. Wir testen, ob der Iterator, den wir durch die Sequenz durchlaufen, dem gegebenen Enditerator entspricht. Wenn dies der Fall ist, wissen wir, dass wir das Ende der Sequenz erreicht haben.
Diese Iteratoren sind weiter in verschiedene Typen mit unterschiedlichen Fähigkeiten unterteilt. Der Iterator eines Vektors gehört zur Kategorie des Direktzugriffs-Iterators. Dies bedeutet, dass Sie von jedem Iterator aus in einer einzigen Operation mit konstanter Zeit an eine beliebige Stelle in der Sequenz gelangen können.Zum Beispiel in dem obigen Beispiel kann ich von Anfang des Vektors bis zum Ende erhalten, indem Sie diese:
std::vector<int>::iterator last = v.begin() + 5; // advance 5 elements from begin
i auch rückwärts gehen kann
std::vector<int>::iterator first= v.end() - 5; // go 5 elements back from the end
Dann gibt es bidirektionale Iteratoren, die erlauben Sie immer noch, in der Reihenfolge vorwärts und rückwärts zu gehen, aber immer nur ein Element (also statt + und - Operatoren haben Sie nur ++ und -). Diese werden beispielsweise für verknüpfte Listen verwendet. Es gibt keine Möglichkeit, 5 Elemente in konstanter Zeit in einer verknüpften Liste zu überspringen, so dass die Implementierung der verknüpften Liste nur bidirektionale Iteratoren, nicht Random-Access, ermöglicht.
Und das kann weiter auf einen Vorwärts-Iterator beschränkt werden (der nur den Operator ++ hat. Die obige ostream_iterator
ist ein Beispiel dafür. Da es einen Stream umschließt, gibt es keine Möglichkeit, mit einem solchen Iterator rückwärts zu gehen .
die meisten anderen Sprachen gefunden
though. C in C# Iteratoren ähnlich wie diejenigen implementieren ++ die einzige ist, ich kenne die
insbesondere etwas wesentlich komplexer (und leistungsstark) implementiert, weil C++ Iteratoren von der entkoppelten Container, in die sie zeigen, können Sie leicht Unterbereiche darstellen (um zum Beispiel die ersten drei Elemente im obigen Vektor zu bezeichnen, könnte ich den Iterator pai verwenden r v.begin(), v.begin() + 3
. Ein weiteres Beispiel ist die find
-Funktion, die in einem Iterator Bereich sucht, und gibt einen Iterator zeigt auf das Element gefunden:
std::vector<int>::iterator result = std::find(v.begin(), v.end(), 3);
Dieses Beispiel sagt den gesamten Vektorbereich für das erste Element mit dem Wert suchen 3. Es gibt einen Iterator zurück, der auf dieses Element zeigt (oder den Enditerator, wenn kein Ergebnis gefunden wurde)
Dieser Iterator kann mit den bereits vorhandenen Iteratoren gepaart werden. So können wir zum Beispiel jetzt im Unterbereich zwischen den Iteratoren suchen Suchergebnis und das Ende der Sequenz:
std::vector<int>::iterator result2 = std::find(result + 1, v.end(), 3);
Also wird oben nach dem nächsten Element mit dem Wert 3 gesucht, beginnend bei 1 nach dem ersten Suchergebnis und endend mit dem Ende der Sequenz. Natürlich wird dann kein Element gefunden, daher gibt es v.end()
zurück.
Können Sie klären, was Sie mit anderen "Arten" von Iteratoren meinen? Meinst du Iteratoren, die Datenstrukturen auf verschiedene Arten durchqueren? – dborba
Ja, genau. . –