Maison >développement back-end >C++ >Comment supprimer en toute sécurité des éléments d'un std :: vector pendant l'itération ?

Comment supprimer en toute sécurité des éléments d'un std :: vector pendant l'itération ?

Patricia Arquette
Patricia Arquetteoriginal
2024-10-30 07:35:02422parcourir

How to Safely Remove Elements from a std::vector During Iteration?

Suppression d'éléments d'un std::Vector pendant l'itération

Lorsque vous avez un vecteur d'éléments et que vous devez supprimer des éléments lors d'une itération , la méthode delete() peut causer des difficultés. L'effacement d'un élément invalide tous les itérateurs pointant vers les éléments suivants.

Itérateurs et effacer()

Considérez le code suivant :

<code class="cpp">std::vector<std::string> m_vPaths;
...
for (auto iter = m_vPaths.begin(); iter != m_vPaths.end(); iter++) {
  std::string strPath = *iter;
  if (::DeleteFile(strPath.c_str())) {
    m_vPaths.erase(iter);
    // Iterators become invalid after erase
  }
}</code>

Après le première suppression de fichier réussie, l'itérateur pointant vers l'élément suivant devient invalide. Cela complique la suite de l'itération.

Utiliser deux vecteurs

Une solution consiste à utiliser deux vecteurs : un pour parcourir et un autre pour stocker les éléments à supprimer . Bien que cela fonctionne, cela introduit une surcharge de mémoire et une complexité supplémentaires.

Structures de données alternatives

Il existe des structures de données plus adaptées à la suppression d'éléments au cours de l'itération, telles que :

  • std::set> (ordonné et unique, naturellement trié par ordre décroissant)
  • std::unordered_set (non ordonné et unique)

Ces structures maintiennent une collection de valeurs triées ou non ordonnées, et la suppression n'invalide pas les autres éléments.

Utilisation de std::remove_if

Vous pouvez également utiliser l'algorithme std::remove_if() pour supprimer des éléments spécifiques du vecteur avant de les supprimer. Cela garantit que les itérateurs restent valides :

<code class="cpp">auto iter_new_end = std::remove_if(m_vPaths.begin(), m_vPaths.end(),
  [](const std::string& strPath) {
    return ::DeleteFile(strPath.c_str());
  });
m_vPaths.erase(iter_new_end, m_vPaths.end());</code>

Conclusion

En fonction de vos besoins spécifiques, vous pouvez choisir la meilleure approche parmi :

  • Utiliser les itérateurs avec prudence
  • Maintenir deux vecteurs
  • Utiliser des structures de données alternatives
  • Employer std::remove_if()

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!

Déclaration:
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