2011-12-23 17 views
9

He estado arriba y abajo stackoverflow e incluso el muy, muy bueno Dr. Dobbs article pero no puedo encontrar una respuesta definitiva a la pregunta.¿Cómo borras * Y CONTINUAS * usando std :: reverse_iterator?

Una sección de la respuesta a la pregunta What are the shortcomings of std::reverse_iterator? dice que podría no ser posible en absoluto.


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: Yo sé que hay otras alternativas, como erase_if(), pero estoy buscando una respuesta a esta pregunta específica.

Respuesta

15

Debe ser sólo

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

Voy a darle una oportunidad . ¿Cómo descubriste esto? (Solo preguntando cómo aprender) – Migs

+0

@Migs, la invariante de los iteradores inversos es: '& * (reverse_iterator (i)) == & * (i - 1)'. Haga un mapa al revés de eso (o simplemente piense en eliminar 'rbegin()') y obtendrá el código en la respuesta. – MSN

+0

Gracias @MSN. Funcionó perfectamente. Leí esa invariable en el artículo de Dobbs, pero supongo que no puedo entender las implicaciones de esto. Seguiré mirando hasta que algo (con suerte) suceda. – Migs

0

La mayoría de las implementaciones erase() que he visto volver la próxima iteración de la secuencia precisamente para este tipo de situaciones, por ejemplo:

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

Esto es correcto. Sin embargo, borrar es un miembro de la estructura, no del iterador. Como tal, si está utilizando un iterador o un reverse_iterator, erase() todavía acepta y devuelve un iterador. No hay r_erase(), que acepta y devuelve un reverse_iterator. –

Cuestiones relacionadas