237 votes

Comment appeler effacer avec un itérateur inversé

J'essaie de faire quelque chose comme ça:

 for ( std::list< Cursor::Enum >::reverse_iterator i = m_CursorStack.rbegin(); i != m_CursorStack.rend(); ++i )
{
    if ( *i == pCursor )
    {
        m_CursorStack.erase( i );
        break;
    }
}
 

Cependant, effacer prend un itérateur et non un itérateur inversé. Existe-t-il un moyen de convertir un itérateur inversé en un itérateur normal ou un autre moyen de supprimer cet élément de la liste?

229voto

0xC0DEFACE Points 2212

Après quelques recherches j'ai trouvé la solution. Apparemment, selon la norme [24.4.1/1] la relation entre le je.base() et i est:

&*(reverse_iterator(i)) == &*(i - 1)

(à partir d'un Dr Dobbs l'article):

alt text

Si vous avez besoin d'appliquer un décalage lors de l'obtention de la base(). Donc la solution est:

m_CursorStack.erase( --(i.base()) );

MODIFIER

La mise à jour de C++11.

reverse_iterator i est inchangé:

m_CursorStack.erase( std::next(i).base() );

reverse_iterator i est avancé:

m_CursorStack.erase( std::advance(i).base() );

Je trouve cela beaucoup plus claire que ma solution précédente. Utilisez celle que vous avez besoin.

17voto

Andrey Points 101

Veuillez noter que m_CursorStack.erase( (++i).base()) peut être un problème s’il est utilisé dans une boucle for (voir la question initiale) car il change la valeur de i. L'expression correcte est m_CursorStack.erase((i+1).base())

13voto

slashmais Points 3924

... ou un autre moyen de supprimer cet élément de la liste?

Cela nécessite le drapeau -std=c++11 (pour auto ):

 auto it=vt.end();
while (it>vt.begin())
{
    it--;
    if (*it == pCursor) //{ delete *it;
        it = vt.erase(it); //}
}
 

4voto

Adam Rosenfield Points 176408

Alors que l'aide de l' reverse_iterators' base() méthode et de décrémentation le résultat fonctionne ici, il est intéressant de noter que reverse_iterators ne sont pas donné le même statut que régulier iterators. En général, vous devriez préférer régulières iterators pour reverse_iterators (ainsi que d' const_iterators et const_reverse_iterators), précisément pour des raisons similaires. Voir Médecin Dobbs " Journal pour une discussion approfondie de la raison.

3voto

Nismo Points 11
typedef std::map<size_t, some_class*> TMap;
TMap Map;
.......

for( TMap::const_reverse_iterator It = Map.rbegin(), end = Map.rend(); It != end; It++ )
{
    TMap::const_iterator Obsolete = It.base();   // conversion into const_iterator
    It++;
    Map.erase( Obsolete );
    It--;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X