2010-07-08 18 views
17

La documentazione di boost specialized iterator adaptors afferma che boost::reverse_iterator "Corregge molti dei difetti di C++ 98 std :: reverse_iterator."Quali sono le carenze di std :: reverse_iterator?

Quali sono queste carenze? Non riesco a trovare una descrizione di queste carenze.

FOLLOW-UP DOMANDA:

Come si fa boost :: reverse_iterator correggere queste carenze?

+1

Spesso era un po '..... prematura. –

+0

Pubblicare come commento da quando sto solo supponendo: le implementazioni precedenti di 'std :: reverse_iterator <>' a volte avevano bug. Boost potrebbe aver semplicemente cercato di isolare contro quella situazione. Forse il commento riguarda più le carenze nelle implementazioni di 'reverse_iterator' piuttosto che le carenze nello standard? –

risposta

10

Bene, il grosso problema è che non sono gli iteratori in avanti, e ci sono cose che si aspettano molto dagli iteratori. Quindi, devi fare alcune conversioni divertenti per far funzionare le cose. Per citarne alcuni problemi

  1. alcune versioni di erase() e insert() richiedono iteratori piuttosto che iteratori inverso. Ciò significa che se si utilizza un iteratore inverso e si desidera insert() o erase(), sarà necessario utilizzare la funzione base() iteratore inverso per mettere le mani su un iteratore in avanti. Non c'è conversione automatica.

  2. base() restituisce l'iteratore di inoltro equivalente all'iteratore inverso in termini di inserimento. Cioè, inserire inserti davanti all'elemento corrente. L'elemento a cui punta l'iteratore inverso, quindi, sarebbe l'elemento sbagliato a cui puntare se base() ti ha dato un iteratore che punta allo stesso elemento. Quindi, punta in avanti e puoi usarlo per l'inserimento.

  3. Perché base() restituisce un iteratore che punta a un elemento diverso, è l'elemento sbagliato da utilizzare per erase(). Se si chiama erase() sull'iteratore da base(), si cancellerebbe un elemento in avanti nel contenitore dall'elemento a cui punta l'iteratore inverso, quindi è necessario incrementare l'iteratore inverso prima di chiamare base() per ottenere l'iteratore di inoltro corretto su utilizzare per erase().

  4. Se è anche possibile utilizzare base() con erase() per cancellare correttamente un elemento dipende interamente dalla vostra implementazione. Funziona con gcc, ma con Visual Studio stanno semplicemente avvolgendo un iteratore in avanti in modo tale che non funzioni per usare erase() quando si tratta di iteratori inversi e Visual Studio. Non ricordo se lo insert() abbia lo stesso problema, ma gli iteratori inversi non funzionano allo stesso modo tra diverse implementazioni di C++ (secondo i ragazzi di Visual Studio, lo standard non era abbastanza chiaro), quindi può essere una specie di peloso usarli per qualcosa di diverso dalla semplice iterazione su un contenitore.

Probabilmente ci sono altre questioni, ma trattare con qualsiasi tipo di iteratore diverso da un non-const, iteratore in avanti in C++ quando si fa qualcosa di diverso semplicemente l'iterazione di un contenitore in grado di ottenere un po 'peloso - se puoi anche fare tutto - perché così tante funzioni richiedono iteratori forward non const, piuttosto che qualsiasi altro tipo di iteratore.

Se si desidera veramente conoscere le differenze tra i vari tipi di iteratore e i problemi associati, si consiglia di leggere AWL di Scott Meyer. Ha un grande capitolo sugli iteratori.

MODIFICA: Per quanto riguarda il modo in cui l'iteratore inverso di Boost corregge tali carenze, temo di non avere la minima idea. Sono a conoscenza di alcune delle carenze dello standard iteratore inverso e sono stato morso da loro in passato, ma non ho mai usato molto Boost, quindi non ho alcuna familiarità con i loro iteratori inversi. Scusate.

+1

Non sono sicuro di vedere cosa stai ricevendo. Il codice che "aspetta" gli iteratori diretti non dovrebbe "notare" alcuna differenza a meno che non facciano cose con un comportamento indefinito ... – Cogwheel

+1

Il modello 'std :: reverse_iterator' in C++ 03 espone la stessa categoria di iteratore dell'iteratore sottostante che deve essere almeno un iteratore bidirezionale, quindi un reverse_iterator è sempre almeno un bi-di iteratore (e quindi un iteratore in avanti). –

+1

Non credo che tu abbia ragione qui. Credo che un reverse_iterator sia, in effetti, un iteratore diretto. Almeno non vedo dove viola questo concetto. –

Problemi correlati