una recorrer listas lista iteradores insertar imprimir eliminar elementos ejemplos código como buscar agregar c++ map iterator stdmap

c++ - recorrer - ¿Cómo puedo eliminar elementos de un std:: map con un iterador?



listas c++ (3)

Si tiene un compilador compatible con C ++ 11, aquí hay una manera fácil de hacerlo:

std::map<K, V>::iterator itr = myMap.begin(); while (itr != myMap.end()) { if (ShouldDelete(*itr)) { itr = myMap.erase(itr); } else { ++itr; } }

La idea es avanzar el iterador desde el inicio del contenedor hasta el final, verificando en cada paso si el par clave / valor actual debe eliminarse. Si es así, eliminamos el elemento iterado utilizando la función de miembro de erase , que luego devuelve un iterador al siguiente elemento en el mapa. De lo contrario, avanzamos el iterador hacia adelante normalmente.

Si no tiene un compilador compatible con C ++ 11, o si está trabajando con una base de código anterior, las cosas son un poco más complicadas. Antes de C ++ 11, la función miembro de erase no devolvería un iterador al siguiente elemento en el mapa. Esto significaba que para eliminar un elemento al iterar, necesitarías usar un baile en tres partes:

  1. Copia el iterador actual.
  2. Avance el iterador actual al siguiente elemento.
  3. Llamar erase en la copia del antiguo iterador.

Esto se muestra aquí:

std::map<K, V>::iterator itr = myMap.begin(); while (itr != myMap.end()) { if (ShouldDelete(*itr)) { std::map<K, V>::iterator toErase = itr; ++itr; myMap.erase(toErase); } else { ++itr; } }

Este proceso fue necesario porque si acaba de llamar a erase en el iterador, lo invalidaría , lo que significa que operaciones como incrementar y disminuir conducirían a un comportamiento indefinido. El código anterior lo itr configurando una copia del iterador, avanzando itr para que esté en el siguiente elemento y luego borre la copia temporal del iterador.

Usando algunos trucos inteligentes, es posible reducir este código a expensas de la legibilidad. El siguiente patrón es común en el código C ++ anterior, pero no es necesario en C ++ 11:

std::map<K, V>::iterator itr = myMap.begin(); while (itr != myMap.end()) { if (ShouldDelete(*itr)) { myMap.erase(itr++); // <--- Note the post-increment! } else { ++itr; } }

El uso del operador de incremento posterior aquí es una forma inteligente de hacer una copia del iterador antiguo (recuerde que un operador postfix ++ devuelve una copia del valor del iterador original) mientras avanza el iterador anterior.

Me gustaría recorrer un std::map y eliminar elementos en función de su contenido. ¿Qué mejor manera de hacerlo?



Esta es una forma simple:

int value_to_delete( 2 ); for( std::map<int, int>::iterator i = mm.begin(); i != mm.end(); ) { if( i->second != value_to_delete ) { mm.erase( i++ ); // advance before iterator become invalid } else { ++i; } }


for(MyMap::iterator it = mymap.begin(); it!=mymap.end(); ) { if(mycondition(it)) it = mymap.erase(it); else it++; }

editar: parece que esto solo funciona en MSVC

edit2: en c ++ 0x esto funciona para contenedores asociativos también