c++ stl iterator deque

Uso de std:: deque:: iterator(en C++ STL) para buscar y eliminar ciertos elementos



(2)

Para usar la expresión borrar-eliminar , harías algo como:

deq.erase(std::remove_if(deq.begin(), deq.end(), [](int i) { return i%2 == 0; }), deq.end());

Asegúrese de #include <algorithm> para hacer que std::remove_if esté disponible.

He encontrado un problema al invocar el siguiente código:

#include<deque> using namespace std; deque<int> deq = {0,1,2,3,4,5,6,7,8}; for(auto it = deq.begin(); it != deq.end(); it++){ if(*it%2 == 0) deq.erase(it); }

que resultó en una falla de segmentación. Después de analizar el problema, encontré que el problema reside en la manera en que el STL maneja los iteradores para deques: si el elemento que se está borrando está más cerca del final del deque, el iterador utilizado para señalar el elemento borrado ahora apuntará al SIGUIENTE elemento, pero no el elemento anterior como vector::iterator hace. Entiendo que la modificación de la condición de bucle de it != deq.end() a it < deq.end() podría resolver el problema, pero me pregunto si hay una manera de atravesar y borrar cierto elemento en un deque en el "forma estándar" para que el código también sea compatible con otros tipos de contenedores.


http://en.cppreference.com/w/cpp/container/deque/erase

Todos los iteradores y referencias son invalidados [...]

Valor de retorno: iterador siguiendo el último elemento eliminado.

Este es un patrón común al eliminar elementos de un contenedor STL dentro de un bucle:

for (auto i = c.begin(); i != c.end() ; /*NOTE: no incrementation of the iterator here*/) { if (condition) i = c.erase(i); // erase returns the next iterator else ++i; // otherwise increment it by yourself }

O como Chris mencionó, podrías usar std::remove_if .