2013-02-27 25 views
5

Ich schreibe ein iterator (eigentlich ist es const_iterator für ein aktuelles Objekt, und ich möchte auch ein reverse_const_iterator auch schaffen.C++ Iterator und Reverse-Iterator

Ich sah mich um, um zu sehen, wie dies zu tun, und ich stolperte über this:

Beachten sie, dass jedoch, wenn ein Iterator umgekehrt wird, ist die umgekehrte Version nicht im Bereich auf das gleiche Element zeigen, aber auf die einem vorausgehende Dies um so zu arrangieren. für die Vergangenheit am Ende Element einer Reihe: Ein It Erator, der auf ein Element extend-the-end in zeigt, wird ein umgekehrter Bereich so geändert, dass er auf das letzte Element (nicht ) des Bereichs zeigt (dies wäre das erste Element des Bereichs, wenn umgekehrt ist). Und wenn ein Iterator für das erste Element in einem Bereich umgekehrt ist, zeigt der umgekehrte Iterator auf das Element vor dem ersten Element (dies wäre das Element am Ende des Bereichs, wenn umgekehrt wurde).

Ist das, was aus der Sicht der Benutzer geschieht, oder wenn Sie dereferenzieren ein reverse_iterator tut es nicht abstrakt diese weg von Ihnen, den Wert/Referenz des Objekts geben Sie denken es zeigt? Ist das nur Implementierungsdetail?

Mein Verständnis war:

for(i = obj.rbegin(); i != obj.rend(); i++) 

zu

for(i = obj.begin(); i != obj.end(); i++) 

außer in umgekehrten entspricht. Und so würde *i im ersten Fall rückwärts durch den Container gehen und im zweiten Fall durch den Container gehen. Ist mein Instinkt richtig?

+2

Es funktioniert einfach. –

+0

Als eine Randnotiz: Wenn Sie mit Iteratoren arbeiten, sollten Sie immer Pre-Inkrement ('++ i') anstelle von Post-Inkrement verwenden, da es effizienter sein kann. –

Antwort

5

Sie haben Recht, dass es eine Abstraktion ist. Der Reverse-Iterator enthält einen normalen Iterator, der auf das Element nach dem Objekt zeigt, das Sie erhalten würden, wenn Sie es dereferenziert hätten. Es ist jedoch nicht nur ein Implementierungsdetail. Der std::reverse_iterator Adapter stellt einen Mitgliedsfunktionsaufruf base bereit, der den zugrundeliegenden Iterator zurückgibt.

Der Standard definiert std::reverse_iterator als Iterator-Adapter mit der folgenden Beziehung zur Iterator seiner Adaptierungs:

Die grundlegende Beziehung zwischen einer umgekehrten Iterator und seinem entsprechenden Iterator i durch die Identität festgestellt wird: &*(reverse_iterator(i)) == &*(i - 1)

eine übliche Verwendung für base ist ein Element aus einem Behälter zu löschen, die wie so erfolgen würde:

it++; 
lst.erase(it.base()); 

Wenn Sie diese, während sie über den Behälter in umgekehrter Iterieren tun möchten, würden Sie tun:

it++; 
std::list<int>::reverse_iterator(lst.erase(it.base())); 
+0

Als eine Nebenfrage, warum sollte es jemals nützlich sein, den Basis-Iterator zu bekommen? – Bingo

+0

@Bingo: Weil Container es erwarten können, wird zum Beispiel 'Erase' als ein 'Iterator' und * nicht * ein' Reverse_iterator' angegeben. –

+0

@Matthieu oh, richtig. Das macht Sinn. – Bingo