Dans la discussion précédente sur ce problème, nous savons tous que l'appel de std::vector::erase entraînera Invalidez uniquement l'itérateur situé après l'élément supprimé . Mais après la suppression d'un élément, l'itérateur à cette position est-il toujours valide (bien sûr, après la suppression, il ne pointe pas vers end()) ?
Une compréhension de la façon dont les vecteurs sont implémentés suggère que cet itérateur peut certainement être utilisé, mais je ne suis pas sûr que cela entraîne un comportement indéfini.
À titre d'exemple, le code suivant supprime tous les entiers impairs d'un vecteur. Ce code provoque-t-il un comportement indéfini ?
<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>
Le code fonctionne bien sur ma machine, mais cela ne me convainc pas qu'il est valide.
Pas tous les itérateurs au niveau ou après l'itérateur passé à effacer seront invalidés.
Cependant, effacer renvoie un nouvel itérateur pointant vers l'élément après l'élément supprimé (ou vers la fin s'il n'y a pas un tel élément). Vous pouvez utiliser cet itérateur pour reprendre l'itération.
Notez que cette méthode de suppression des éléments impairs est très inefficace : chaque fois qu'un élément est supprimé, tous les éléments qui le suivent doivent être décalés d'une position vers la gauche dans le vecteur (c'est O(n2 )). Vous pouvez accomplir cette tâche plus efficacement (O(n)) en utilisant l'idiome Erase-Remove. Vous pouvez créer un prédicat is_odd :
<code class="cpp">bool is_odd(int x) { return (x % 2) == 1; }</code>
Ensuite, vous pouvez le passer à remove_if :
<code class="cpp">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!