7
votes

Comment itérer sur un ensemble STL et supprimer sélectivement des éléments?

Le code suivant ne fonctionne pas correctement. Comment devrait-il être fait correctement? XXX


0 commentaires

3 Réponses :


7
votes

Essayez:

for(std::set<Color>::iterator it = myColorContainer.begin(); 
    it != myColorContainer.end();) { // note missing it++
     if( (*it) == Yellow ) {
        DoSomeProcessing(*it);
        myColorContainer.erase(it++); // post increment (original sent to erase)
     }
     else {
       ++it; // more efficient than it++;
     }
}


3 commentaires

Cela ne fonctionnera pas non plus. Vous devez affecter la valeur de retour d'effacement à nouveau.


L'itérateur renvoyé est une implémentation spécifique à Microsoft qui enfreint la norme: msdn.microsoft.com/en-us/library/8H4A3515%28VS.80%29.aspx . Assez sûr, vous devez incrémenter l'itérateur après l'effacement.


Cette Sollution est parfaite si vous ne pouvez pas utiliser la mise en œuvre de M $ et la possibilité d'utiliser une boucle. Si vous n'avez pas besoin d'utiliser une boucle, l'option de Viktor est encore meilleure. Merci pour une bonne réponse. Vous avez été une bonne aide.



6
votes

Vous n'avez pas besoin d'une boucle comme vous avez eu votre trace avec un ensemble.

std::set<Color>::iterator it = myColorContainer.find(Yellow);
if (it != it.myColorContainer.end()){
  DoSomeProcessing(*it);
  myColorContainer.erase(it);
}


2 commentaires

Le code est conforme aux normes. Je suis d'accord @viktor Sehr ce serait le moyen préféré de supprimer un élément de l'ensemble. Cependant, la question demande comment faire fonctionner le code de code.


@daramarak: Je pense que vous avez répondu pendant que j'ai édité le code (pensais c'était un std :: Vecteur de mon premier post)



2
votes
for (std::set<Color>::iterator i = myColorContainer.begin();
            i!=myColorContainer.end(); /* No i++ */)
{
    if ( *i  == Yellow)
    {
        DoSomeProccessing( *i );
        std::set<Color>::iterator tmp = i;
        ++i;
        myColorContainer.erase(tmp);
    }
    else {
        ++i;
    }
}
Once you go to next message with ++i it is guaranteed to be valid - property of std::set that iterators on inserted elements are never invalidated unless the element
is removed.So now you can safely erase previous entry.

0 commentaires