Ein Iterator ist ein ausgefeilter Zeiger. Wie ein Zeiger zeigt es zu unterschiedlichen Zeiten auf Objekte des gleichen Typs im Speicher. Alle Iteratoren sind derenferenzierbar, mit Ausnahme des Ausgangs -Iterators, der nur für eine Reihe von Typen derenferenzierbar ist. Dereferencable bedeutet, dass der vom Zeiger oder Iterator gerichtete Wert unter Verwendung des Indirektionoperators * erhalten werden kann. Eine Ganzzahl kann einigen Iteratoren auf die gleiche Weise hinzugefügt werden, und für den gleichen Zweck würde die Ganzzahl einem Zeiger hinzugefügt werden.
Die Fragen zu diesem Artikel sind: Was sind diese Iteratoren? Welche dieser Iteratoren werden mit dem C ++ - Vektor verwendet?? Wie werden diese Iteratoren mit dem C ++ - Vektor verwendet?? Dieser Artikel beantwortet all diese Fragen auf vereinfachte Weise. Am Ende dieses Artikels, wenn all diese Fragen beantwortet worden wären, sind C ++ Vektor -Iteratoren intuitiv und natürlich (für den Leser).
Artikelinhalt
Zusammenfassung von C ++ - Iteratoren
Eingabe -Iterator
Die Idee des Eingabe -Iterators besteht darin, dass ein Programm den Eingabewert empfängt. Im Gegensatz zum Ausgang Iterator ist der Eingang Iterator immer Derferenzierbar. Für zwei Eingabe -Iteratoren, A und B, impliziert "A == B" nicht "++ A == ++ B".
Iterator ausgeben
Die Idee des Ausgabe -Iterators besteht darin, dass ein Programm den Ausgangswert freigibt. Im Gegensatz zum Eingabe -Iterator ist der Ausgang Iterator nicht immer derenferenzierbar. Es ist nur für eine Reihe von Typen derenferenzierbar.
Vorwärts -Iterator
Der Vorwärts -Iterator kann den Vektor von Anfang bis Ende nacheinander scannen (Inkrementierung). Es hat alle Anforderungen des Eingabe -Iterators sowie zusätzliche Anforderungen. Es kann einen Eingangs -Iterator ersetzen. Für zwei Vorwärts -Iteratoren, A und B, impliziert "A == B" "++ A == ++ B".
Bidirektionaler Iterator
Der bidirektionale Iterator kann den Vektor von Anfang bis Ende nacheinander scannen. Vom Ende bis zum Anfang, nacheinander (dekrementiert). Es hat alle Anforderungen des Vorwärts -Iterators sowie zusätzliche Anforderungen. Es kann einen Vorwärts -Iterator ersetzen. Für zwei bidirektionale Iteratoren, a und b,
"A == B" impliziert "++ A == ++ B"
Und
"-A == -b" impliziert "a == b".
Random Access Iterator
Der Zufallszugriffs -Iterator hat alle Anforderungen des bidirektionalen Iterators sowie zusätzliche Anforderungen. Es kann einen bidirektionalen Iterator ersetzen. Der Zufallszugriffs -Iterator hat den Vorteil, dass es die zweite und dritte Elemente überspringen und auf das vierte Element verweisen würde, wenn er derzeit auf das erste Element hinweist und das vierte Element erforderlich ist. Der Rückwärtssprung nach unten ist wahr.
Rückwärts -Iterator
Beachten Sie, dass C ++ keinen normalen Umkehr -Iterator hat, da er einen Vorwärts -Iterator hat. Es gibt also einen Adapter, der als Reverse Iterator bezeichnet wird. Es gibt mehr gute Nachrichten: Der umgekehrte Iterator erfüllt alle Anforderungen eines bidirektionalen Iterators.
Ständiger Iterator
Wenn ein Iterator als Const -Iterator bezeichnet wird, kann das Element, auf das er verweist, nicht geändert werden.
Vektorkonstruktion und Zugang
Container in C ++ sind: Klassenarray, Deque, ForeVe_List, List, Vector, Map, Set, Under Ordered_map und Unordned_Set. Der Vektor ist ein Behälter. Bestimmte Funktionsvorlagen in der C ++ - Standardbibliothek arbeiten direkt oder indirekt mit Iteratoren. C ++ - Container sowie der Vektor verwenden diese Funktionen. Diese Funktionen können dem C ++ - Programm mit einer der folgenden Einschlussrichtlinien zur Verfügung gestellt werden:
#enthalten
oder
#enthalten
Durch die Einbeziehung eines anderen Containers wird diese Funktionsvorlagen auch zur Verfügung gestellt. Eine Funktionsvorlage gilt für eine Funktion, die mit unterschiedlichen Datentypen arbeiten kann. Der Vektor verwendet Iteratoren durch diese Funktionsvorlagen. Einige der Funktionsvorlagen und ihre Beziehung zum Vektor sind wie folgt:
Konstruktion
Vorlagenfunktion:
Vorlagecontexpr automatische Daten (C & C) -> deklart (c).Daten());
Auto bedeutet, dass der Rückgabetyp bei der Bewertung der Funktion bestimmt wird. C ist das Objekt der Klasse C.
Ein Beispiel für ein mit diesem implizit konstruierten Vektorobjekt ist:
Vektorvtr;
Hier ist das Objekt C leer.
Vorlagenfunktion:
VorlageconstExpr const e* Daten (initializer_list il) noexcept;
Hier ist E* ein Iterator, der auf das erste Element der Liste oder des Containers verweist. Die Verwendung mit dem Vektor wäre implizit mit:
Vektorvtr 'a', 'b', 'c', 'd', 'e';
Vektor:: const_iterator it = vtr.Start();
Die Vorlagenfunktion gilt eher für die Anweisung an Anfang () (die zweite Anweisung).
Zugang
Vorlagenfunktion:
VorlageCONTEXPR -Autogröße (const c & c) -> deklarttype (c).Größe());
Dies gibt die Größe des Behälters zurück. Vektorbeispiel:
Vektorvtr 'a', 'b', 'c', 'd', 'e';
int n = vtr.Größe();
Cout << N << endl;
Der Ausgang ist 5.
Vorlagenfunktion:
Vorlage[[nodiscard]] contexpr bool leer (initializer_list il) noexcept;
Gibt true zurück, wenn die Liste sonst leer oder falsch ist. Vektorbeispiel:
Vektorvtr 'a', 'b', 'c', 'd', 'e';
bool bl = vtr.leer();
Cout << bl << endl;
Die Ausgabe ist 0 für false.
Bereichszugriff
Es gibt andere Vorlagenfunktionen, die Iteratoren verwenden, die der Vektor für seine Bereichsprobleme verwendet. Ein Bereich ist ein aufeinanderfolgender Satz von Containerelementen.
Vorlagenfunktion:
Vorlagecontexpr auto begin (c & c) -> decltype (c).Start());
Dies gibt einen Iterator zurück, der auf das erste Element in der Liste zeigt. Auto bedeutet hier, der Rückgabewert wird bei der Bewertung bestimmt. Beispiel für Vector:
Vektorvtr 'a', 'b', 'c', 'd', 'e';
Vektor:: iterator it = vtr.Start();
Cout << *it << '\n';
Die Ausgabe ist a. Der hier zurückgegebene Iterator ist ein Zufallszugriffs -Iterator. Ein konstanter Zufallszugriffs -Iterator hätte zurückgegeben werden können - später siehe.
Funktionsvorlage:
Vorlagecontexpr auto end (const c & c) -> decltype (c).Ende());
Gibt einen konstanten Iterator zurück, der auf das letzte Element der Liste zeigt. Vektorcode:
Vektorvtr 'a', 'b', 'c', 'd', 'e';
Vektor:: const_iterator it = vtr.Ende();
--Es;
Cout << *it << ";
--Es;
Cout << *it << endl;
Die Ausgabe ist "e d". Ein konstanter Iterator kann inkrementiert oder verringert werden, aber der Wert, auf den er hinweist, kann nicht geändert werden. Ein normaler Zufallszugriffs -Iterator hätte zurückgegeben werden können - später siehe.
Funktionsvorlage:
Vorlagecontexpr revers_iterator rbegin (initializer_list il);
Gibt den letzten Wert in der Liste zurück. rbegin () zeigt auf das letzte Element der Liste und nicht über das letzte Element der Liste hinaus, wie es end () tut. Vektorbeispiel:
Vektorvtr 'a', 'b', 'c', 'd', 'e';
Vektor:: Reverse_iterator it = vtr.rbegin ();
Cout << *it << ";
++Es;
Cout << *it << endl;
Die Ausgabe ist: e d. Mit dem umgekehrten Iterator hat ++ den gegenteiligen Effekt für den bidirektionalen Iterator.
Funktionsvorlage:
Vorlagecontexpr revers_iterator rend (initializer_list il);
Punkte kurz vor dem ersten Element der Liste. Vektorbeispiel:
Vektorvtr 'a', 'b', 'c', 'd', 'e';
Vektor:: Reverse_iterator it = vtr.zerreißen();
--Es;
Cout << *it << ";
--Es;
Cout << *it << endl;
Ausgabe ist a b. Mit dem umgekehrten Iterator hat - den gegenteiligen Effekt für ++ des bidirektionalen Iterators.
Es gibt andere Vorlagenfunktionen unter dieser Überschrift - siehe später.
Iteratoren einfügen
Reverse_iterator ist ein Iteratoradapter, nicht wirklich ein Iterator. Der Iterator des Einsatzes ist auch ein Iteratoradapter. Es erfüllt alle Anforderungen des Ausgabe -Iterators sowie seine eigenen Anforderungen. Es existiert in drei Formen in C ++: The Back_inserter, The Front_inSerter und das Inserter. Jeder von diesen hat seinen eigenen Konstruktor.
Back_inserter:
Einsätze auf der Rückseite!
Wichtige Prototypen:
explizite back_insert_iterator (Container & x);
back_insert_iterator & operator = (Typename container :: value_type && value);
Vektorbeispiel:
Der Vektor hat keine Einsatzelementfunktion, die auf der Rückseite einfügt. Die Member -Funktion Push_back (T) ist jedoch so zu sehen.
Front_inserter
Einsätze vorne vorne!
Wichtige Prototypen:
explizite front_insert_iterator (Container & x);
Front_insert_iterator & operator = (Typename container :: value_type && value);
Vektorbeispiel:
Der Vektor hat keine Einsatzelementfunktion, die vorne einfügt. Der Vektor hat auch nicht die Member -Funktion PUSP_FRONT (T).
Die gute Nachricht ist, dass der Vektor Mitgliedsfunktionen einfügen, die überall, am Anfang, innerhalb oder am Ende des Vektors einfügen können.
Inserter
Dieser Iterator würde am Anfang, innerhalb oder am Ende des Vektors einfügen.
Wichtige Prototypen:
Insert_iterator (Container & X, TypName Container :: Iterator I);
Insert_iterator & operator = (Typename container :: value_type && value);
Vektorbeispiel:
Vektorvtr 'a', 'b', 'c', 'd', 'e';
Vektor:: iterator it = vtr.Start();
es = es + 2;
vtr.einfügen (es, 'c');
für (int i = 0; iCout << vtr[i] << ", ";
Cout <Die Ausgabe ist:
A, b, c, c, d, e,Der Vektoreinsatzausdruck lautet:
vtr.einfügen (es, 'c');Es fügt das Element kurz vor dem Zeiger (es) ein, auf den es zeigt.
Iterator bewegen
Der Move_iterator ist auch ein Iteratoradapter. Das folgende Programm ähnelt dem Beispiel in der C ++ - Spezifikation:
#enthalten
#enthalten
#enthalten
Verwenden von Namespace STD;
int main ()
Listechs 'a', 'b', 'c', 'd', 'e';
Vektorvtr (make_move_iterator (chs.begin ()), make_move_iterator (chs.Ende()));
Cout << "Original list Content:" << endl;
für (auto it = chs.Start(); Es != CHS.Ende(); es ++)
Cout << *it << ", ";
Cout << endl << endl;
Cout << "Vector Content:" << endl;
für (int i = 0; iCout << vtr[i] << ", ";
Cout << endl;
Rückkehr 0;Die Ausgabe ist:
Originallisteninhalt:
A, b, c, d, e,Vektorinhalt:
A, b, c, d, e,Dieser Iterator wandelt einen Quellwert in ein RValue um, bevor er ihn am Ziel platziert.
Abschluss
Die Haupt-Iteratoren in C ++ sind Eingangs-Iterator, Ausgangs-Iterator, Vorwärts-Iterator, bidirektionaler Iterator und Zufallszugriff Iterator. Die C ++ - Standardbibliothek verfügt über einige Funktionsvorlagen, die diese Iteratoren verwenden. Der Vektor verwendet diese Iteratoren durch die Funktionsvorlagen. Der Vektor hat für einige dieser Iteratoren einige unterschiedliche Namen. Es gibt auch Iteratoradapter, nämlich: Reverse_iterator, Iteratoradapter und Move_iterator. Es gibt auch einige Varianten von Iteratoren. Es reicht aus, in ein Programm aufzunehmen, um all diese Funktionen zu haben. Nach dem Verständnis der Rolle dieser Iteratoren, Adapter und der Funktionsvorlagen, die sie verwenden, wird die Verwendung von Iteratoren mit Vektoren intuitiv.