2013-02-27 12 views
5

sto scrivendo un iterator (in realtà è const_iterator per il mio oggetto corrente, e voglio anche creare un reverse_const_iterator anche.C++ iteratore e invertire iteratore

mi sono guardato intorno, per vedere come fare questo e io imbattuto this:.

Avviso tuttavia che quando un iteratore viene invertito, la versione invertita non punta allo stesso elemento della gamma, ma a quello precede Questo è così, al fine di organizzare per il passato l'elemento di un intervallo: An it l'erator che punta a un elemento passato-fine in un intervallo, quando invertito, viene modificato in modo che punti all'ultimo elemento (non passato) dell'intervallo (questo sarebbe il primo elemento dell'intervallo se invertito). E se un iteratore del primo elemento di un intervallo è invertito, l'iteratore invertito punta all'elemento prima del primo elemento (questo sarebbe l'elemento passato-fine dell'intervallo se invertito).

È questo ciò che succede dal punto di vista degli utenti, o quando si dereference un reverse_iterator lo fa non astratta questa via dando il valore/di riferimento dell'oggetto che si pensa si sta puntando? Questo è solo un dettaglio di implementazione?

mia comprensione è:

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

era equivalente a

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

tranne che in senso inverso. E così *i tornerebbe indietro nel contenitore nel primo caso e andrà avanti attraverso il contenitore nel secondo caso. Il mio istinto è corretto?

+2

Funziona. –

+0

Come nota a margine: quando si lavora con gli iteratori si dovrebbe sempre usare il pre-incremento ('++ i') invece del post-incremento poiché può essere più efficiente. –

risposta

5

Hai ragione che è un'astrazione. L'iteratore inverso contiene un normale iteratore che punta sull'elemento dopo l'oggetto che avresti ricevuto se lo avevi rinviato. Tuttavia, non è solo un dettaglio di implementazione. L'adattatore std::reverse_iterator fornisce una chiamata di funzione membro base che restituisce l'iteratore sottostante.

Lo standard definisce std::reverse_iterator come adattatore iteratore con la seguente relazione all'iteratore suo adattamento:

La relazione fondamentale tra un iteratore inverso e il corrispondente iteratore i è stabilito dall'identità: &*(reverse_iterator(i)) == &*(i - 1)

un uso comune per base sta cancellando un elemento da un contenitore, che dovrebbe essere fatto in questo modo:

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

Se si vuole fare questo, mentre l'iterazione sopra il contenitore in senso inverso, si dovrebbe fare:

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

Come una domanda a parte, perché sarebbe mai utile ottenere il 'base' sottostante' iteratore'? – Bingo

+0

@Bingo: poiché i contenitori possono aspettarselo, ad esempio, 'cancella' è specificato come prendendo un' iteratore' e * non * un 'reverse_iterator'. –

+0

@Matthieu oh, giusto. Ciò ha senso. – Bingo