Maison > développement back-end > C++ > Comment itérer et supprimer en toute sécurité des éléments d'une liste std :: ?

Comment itérer et supprimer en toute sécurité des éléments d'une liste std :: ?

Patricia Arquette
Libérer: 2025-01-04 15:31:40
original
487 Les gens l'ont consulté

How to Safely Iterate and Remove Elements from a std::list?

Itérer et supprimer des éléments d'une std::list

Supprimer des éléments d'une std::list lors d'une itération nécessite une manipulation minutieuse pour évitez d’invalider l’itérateur. Une idée fausse courante consiste à supposer que la suppression d’un élément immédiatement après son évaluation incrémentera correctement l’itérateur. Cependant, cette approche conduit à l'erreur « Itérateur de liste non incrémentable ».

Comprendre le comportement de l'itérateur

Dans une std::list, les éléments sont alloués de manière contiguë. Lorsqu'un élément est supprimé, les éléments suivants se déplacent pour remplir l'espace libéré. Par conséquent, l’itérateur pointant initialement vers l’élément supprimé devient invalide. L'incrémentation de cet itérateur entraînera un comportement indéfini.

Approche correcte : incrémenter d'abord, supprimer plus tard

Pour supprimer correctement des éléments lors de l'itération, adoptez la stratégie suivante :

  1. Incrémentez d'abord l'itérateur : Utilisez i pour déplacer l'itérateur vers l'élément suivant avant de supprimer quoi que ce soit.
  2. Supprimez l'élément précédent : Utilisez items.erase(i ) pour supprimer l'élément qui était avant la position actuelle, où i renvoie un itérateur à l'élément suivant. Alternativement, vous pouvez utiliser i = items.erase(i); pour obtenir le même résultat.

Code modifié à l'aide d'une boucle While :

std::list<item*>::iterator i = items.begin();
while (i != items.end()) {
    bool isActive = (*i)->update();
    if (!isActive) {
        items.erase(i++);  // alternatively, i = items.erase(i);
    } else {
        other_code_involving(*i);
        ++i;
    }
}
Copier après la connexion

Ce code modifié parcourt la liste et :

  1. Appelle update() sur chaque élément.
  2. Si l'élément est inactif, le supprime et déplace le itérateur vers l'élément suivant.
  3. Si l'élément est actif, exécute un autre code et incrémente l'itérateur.

Éviter l'approche Remove_if

Votre code d'origine incluait un appel remove_if() après la boucle. Cette approche est généralement déconseillée dans ce contexte car elle nécessite un passage supplémentaire sur la liste. L'itération et la suppression en un seul passage, comme indiqué ci-dessus, sont une solution plus efficace et plus simple.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal