Beaucoup plus élégant solution serait de passer à std::list
(en supposant que vous n'avez pas besoin d'accès aléatoire rapide).
list<Widget*> widgets ; // create and use this..
Vous pouvez ensuite les supprimer avec .remove_if
et un C++ foncteur en une seule ligne:
widgets.remove_if( []( Widget*w ){ return w->isExpired() ; } ) ;
Donc ici, je suis en train d'écrire un foncteur qui accepte un argument ( Widget*
). La valeur de retour est la condition de supprimer un Widget*
à partir de la liste.
Je trouve cette syntaxe acceptable. Je ne pense pas que j'aurais jamais les utiliser, remove_if
pour les std::vecteurs -- il y a tellement d' inv.begin()
et inv.end()
le bruit de là, vous êtes probablement mieux d'utiliser un entier fondé sur l'indice de supprimer ou juste un simple vieux régulières itérateur à base de supprimer (comme illustré ci-dessous). Mais vous ne devrait pas vraiment être enlever du milieu d'un std::vector
beaucoup de toute façon, le fait de passer à un list
pour ce cas de fréquentes moyen de la liste de suppression est conseillé.
Notez cependant je n'ai pas de possibilité d'appeler d' delete
sur le Widget*
's qui ont été supprimés. Pour ce faire, il devrait ressembler à ceci:
widgets.remove_if( []( Widget*w ){
bool exp = w->isExpired() ;
if( exp ) delete w ; // delete the widget if it was expired
return exp ; // remove from widgets list if it was expired
} ) ;
Vous pouvez également utiliser un itérateur à base de boucle comme ceci:
// NO INCREMENT v
for( list<Widget*>::iterator iter = widgets.begin() ; iter != widgets.end() ; )
{
if( (*iter)->isExpired() )
{
delete( *iter ) ;
iter = widgets.erase( iter ) ; // _advances_ iter, so this loop is not infinite
}
else
++iter ;
}
Si vous n'aimez pas la longueur de l' for( list<Widget*>::iterator iter = widgets.begin() ; ...
, vous pouvez utiliser
for( auto iter = widgets.begin() ; ...