6 votes

Utilisation de std::deque::iterator (dans la STL C++) pour la recherche et la suppression de certains éléments

J'ai rencontré un problème en invoquant le code suivant :

#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);
}

ce qui a entraîné un défaut de segmentation. Après avoir examiné le problème, j'ai découvert que le problème réside dans la façon dont la STL gère les itérateurs pour les deques : si l'élément en cours d'effacement est plus proche de la fin du deque, l'itérateur utilisé pour pointer sur l'élément effacé pointera maintenant sur l'élément NEXT, mais pas sur l'élément précédent, car vector::iterator fait. Je comprends que modifier la condition de la boucle de it != deq.end() à it < deq.end() pourrait éventuellement résoudre le problème, mais je me demande s'il existe un moyen de parcourir et d'effacer certains éléments dans un deque dans la "forme standard" afin que le code soit également compatible avec d'autres types de conteneurs.

19voto

syam Points 9352

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

Tous les itérateurs et références sont invalidés [...].

Valeur de retour : itérateur suivant le dernier élément retiré.

Il s'agit d'un modèle courant lorsque l'on retire des éléments d'un conteneur STL à l'intérieur d'une boucle :

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
}

Ou comme chris mentionné que vous pourriez simplement utiliser std::remove_if .

11voto

Fraser Points 20579

Pour utiliser le effacer-renverser idiome vous feriez quelque chose comme :

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

Veillez à #include <algorithm> de faire std::remove_if disponible.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X