2011-12-23 14 views
9

Sono stato su e giù per stackoverflow e anche molto, molto bello Dr. Dobbs article ma non riesco a trovare una risposta definitiva alla domanda.Come si cancella * E CONTINUA * usando uno std :: reverse_iterator?

Una sezione della risposta alla domanda What are the shortcomings of std::reverse_iterator? afferma che potrebbe non essere possibile.


std::list::reverse_iterator it = list.rbegin(); 

while( it != list.rend()) 
{ 
    int value=*it; 
    if(some_cond_met_on(value)) 
    {  
     ++it; 
     list.erase(it.base()); 
    } 
    else 
    { 
    ++it; 
    } 
} 

PS: Io so che ci sono altre alternative, come ad esempio erase_if(), ma sto cercando una risposta a questa specifica domanda.

risposta

15

Dovrebbe essere solo

std::list<int>::reverse_iterator it = list.rbegin(); 

while( it != list.rend()) 
{ 
    int value=*it; 
    if(some_cond_met_on(value)) 
    {  
     ++it; 
     it= reverse_iterator(list.erase(it.base()); // change to this! 
    } 
    else 
    { 
    ++it; 
    } 
} 
+0

darò una prova . Come hai capito questo? (Solo chiedendo di imparare come imparare) – Migs

+0

@Migs, l'invariante degli iteratori inversi è: '& * (reverse_iterator (i)) == & * (i - 1)'. Mappa indietro (o pensa solo a eliminare 'rbegin()') e ottieni il codice nella risposta. – MSN

+0

Grazie a @MSN. Ha funzionato perfettamente. Ho letto quell'invarianza nell'articolo di Dobbs, ma immagino che non riesca a coglierne le implicazioni. Continuerò a fissare finché qualcosa (si spera) non accadrà. – Migs

0

La maggior parte delle implementazioni erase() ho visto tornare il prossimo iteratore nella sequenza proprio per questo tipo di situazione, per esempio:

std::list<int>::reverse_iterator it = list.rbegin(); 
while(it != list.rend()) 
{ 
    int value = *it; 
    if(some_cond_met_on(value)) 
    { 
     it = list.erase(it); 
    } 
    else 
    { 
     ++it; 
    } 
} 
+0

Questo è corretto. Tuttavia, cancellare è un membro della struttura, non l'iteratore. Pertanto, se si sta utilizzando un iteratore o un reverse_iterator, cancella() accetta e restituisce un iteratore. Non esiste r_erase(), che accetta e restituisce un reverse_iterator. –

Problemi correlati