Maison >développement back-end >C++ >## L'itérateur à la position effacée dans std::vector::erase() est-il toujours valide ?
Comprendre l'invalidation de l'itérateur dans std::vector::erase()
Dans cette discussion, nous abordons le sujet de l'invalidation de l'itérateur lorsque en appelant std::vector::erase(). Comme l'ont montré les débats précédents, il est établi que l'effacement d'un élément d'un vecteur invalide les itérateurs situés après l'élément effacé. Cependant, une question se pose : l'itérateur positionné au niveau de l'élément effacé est-il toujours considéré comme valide ?
Malgré notre compréhension intuitive que l'itérateur situé à la position effacée doit rester utilisable, le comportement précis n'est pas toujours clair. Pour illustrer ce concept, analysons l'extrait de code suivant qui supprime tous les entiers impairs d'un vecteur :
<code class="cpp">typedef std::vector<int> vectype; vectype vec; for (int i = 0; i < 100; ++i) vec.push_back(i); vectype::iterator it = vec.begin(); while (it != vec.end()) { if (*it % 2 == 1) vec.erase(it); else ++it; }</code>
Bien que ce code s'exécute avec succès, il enfreint les meilleures pratiques. Selon la norme C, delete() invalide tous les itérateurs au niveau ou après le(s) itérateur(s) fourni(s) en paramètres. Dans ce cas, cela signifie que l'itérateur à la position effacée devient invalide.
Cependant, effacer() renvoie commodément un nouvel itérateur qui pointe vers l'élément qui suit immédiatement le ou les éléments effacés, ou vers vec.end () si aucun élément de ce type n'existe. Ce nouvel itérateur peut être utilisé pour reprendre l'itération en toute sécurité.
Il est important de noter que la méthode susmentionnée de suppression des éléments impairs n'est pas efficace. Chaque fois qu'un élément est supprimé, les éléments suivants doivent être décalés vers la gauche dans le vecteur, ce qui entraîne une complexité O(n2). Cette tâche peut être accomplie plus efficacement en utilisant l'idiome effacer-supprimer, qui fonctionne en O(n). En créant un prédicat comme is_odd(), on peut affiner l'opération d'effacement :
<code class="cpp">bool is_odd(int x) { return (x % 2) == 1; } vec.erase(std::remove_if(vec.begin(), vec.end(), is_odd), vec.end());</code>
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!