Invalidation des itérateurs std :: vector : une explication détaillée
Le concept d'invalidation d'itérateur dans std :: vector a été fréquemment discuté. Pour clarifier, l'effacement des éléments vectoriels via std::vector::erase invalide les itérateurs positionnés strictement après l'élément effacé.
Cependant, la validité de l'itérateur à la position exacte de l'élément effacé reste incertaine. Logiquement, on pourrait supposer que cet itérateur reste valide puisque l'implémentation sous-jacente du vecteur décale généralement les éléments restants pour remplir l'espace vide. Cependant, le comportement précis et le potentiel de résultats indéfinis sont moins certains.
Considérons l'exemple suivant, qui illustre la suppression d'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>
Alors que ce code semble s'exécute sans erreur en pratique, sa validité reste discutable.
La réponse réside dans le comportement de l'effacement : il invalide en effet tous les itérateurs au niveau ou après le(s) itérateur(s) passé(s) à effacer. Cependant, il renvoie également un nouvel itérateur immédiatement après le ou les éléments effacés ou à la fin si un tel élément n'existe pas. Cet itérateur peut être utilisé pour reprendre l'itération.
Il est important de noter que la méthode ci-dessus de suppression des entiers impairs est inefficace (O(n2)) car chaque effacement nécessite un décalage de tous éléments ultérieurs. L'idiome effacer-supprimer offre une solution beaucoup plus efficace (O(n)) :
<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!