vector erase iterator

J’ai ce code:

int main() { vector res; res.push_back(1); vector::iterator it = res.begin(); for( ; it != res.end(); it++) { it = res.erase(it); //if(it == res.end()) // return 0; } } 

“Un iterator d’access aléatoire pointant vers le nouvel emplacement de l’élément qui a suivi le dernier élément effacé par l’appel de fonction, qui est la fin du vecteur si l’opération a effacé le dernier élément de la séquence.”

Ce code plante mais si j’utilise le if (il == res.end ()) et le retourne ensuite, il fonctionne. Comment venir? La boucle for encaisse-t-elle res.end () de sorte que l’opérateur non égal échoue?

res.erase(it) renvoie toujours le prochain iterator valide, si vous effacez le dernier élément, il pointe vers .end()

A la fin de la boucle ++it est toujours appelé, donc vous incrémentez .end() qui n’est pas autorisé.

La simple vérification de .end() laisse néanmoins un bogue, car vous ignorez toujours un élément à chaque itération ( it est incrémenté par le retour de .erase() , puis à nouveau par la boucle)

Vous voulez probablement quelque chose comme:

  while (it != res.end()) { it = res.erase(it); } 

effacer chaque élément

(pour être complet: je suppose que c’est un exemple simplifié, si vous voulez simplement que chaque élément disparaisse sans avoir à effectuer une opération dessus (par exemple, supprimer), vous devez simplement appeler res.clear() )

Lorsque vous effacez uniquement des éléments, vous voulez probablement quelque chose comme

 for ( ; it != res.end(); ) { if (condition) { it = res.erase(it); } else { ++it; } } 
 for( ; it != res.end();) { it = res.erase(it); } 

ou plus général:

 for( ; it != res.end();) { if (smth) it = res.erase(it); else ++it; } 

En guise de modification à la réponse de crazylammer, j’utilise souvent:

 your_vector_type::iterator it; for( it = res.start(); it != res.end();) { your_vector_type::iterator curr = it++; if (something) res.erase(curr); } 

L’avantage de ceci est que vous n’avez pas à vous soucier d’oublier d’incrémenter votre iterator, le rendant moins sujet aux bogues lorsque vous avez une logique complexe. À l’intérieur de la boucle, curr ne sera jamais égal à res.end (), et il sera à l’élément suivant, que vous l’effaciez ou non de votre vecteur.

Ne pas effacer et puis incrémenter l’iterator. Pas besoin d’incrémenter, si votre vecteur a un nombre impair (ou même je ne sais pas) d’éléments, vous allez manquer la fin du vecteur.

L’instruction it ++ est effectuée à la fin du bloc. Donc, si vous effacez le dernier élément, vous essayez d’incrémenter l’iterator qui pointe vers une collection vide.

Vous l’incrémentez après la fin du conteneur (vide) dans l’expression de boucle de la boucle for.

Ce qui suit semble également fonctionner:

 for (vector::iterator it = res.begin(); it != res.end(); it++) { res.erase(it--); } 

Vous ne savez pas s’il y a des défauts?

 if(allPlayers.empty() == false) { for(int i = allPlayers.size() - 1; i >= 0; i--) { if(allPlayers.at(i).getpMoney() <= 0) allPlayers.erase(allPlayers.at(i)); } } 

Cela fonctionne pour moi. Et pas besoin de penser aux index déjà effacés.

Parce que la méthode efface dans vector renvoie l’iterator suivant de l’iterator passé.

Je vais vous donner un exemple de comment supprimer un élément dans un vecteur lors d’une itération.

 void test_del_vector(){ std::vector vecInt{0, 1, 2, 3, 4, 5}; //method 1 for(auto it = vecInt.begin();it != vecInt.end();){ if(*it % 2){// remove all the odds it = vecInt.erase(it); // note it will = next(it) after erase } else{ ++it; } } // output all the remaining elements for(auto const& it:vecInt)std::cout< 

sortie aw ci-dessous:

 024 024 024 

Une méthode plus générasortingce:

 template void erase_where(Container& c, F&& f) { c.erase(std::remove_if(c.begin(), c.end(),std::forward(f)), c.end()); } void test_del_vector(){ std::vector vecInt{0, 1, 2, 3, 4, 5}; //method 4 auto is_odd = [](int x){return x % 2;}; erase_where(vecInt, is_odd); // output all the remaining elements for(auto const& it:vecInt)std::cout<