2012-04-05 11 views
9

È possibile cancellare un elemento puntato dall'iteratore e far avanzare lo stesso iteratore su una riga per passare all'elemento successivo?C++ set iterator removal

set<int>::iterator it = S.begin(); 
while (it != S.end()) { 
    if (shouldBeRemoved(*it)) { 
     S.erase(it++); // is this line valid? 
    } else { 
     ++it; 
    } 
} 

risposta

5

E 'consentito di cancellare un elemento puntato da iteratore, e far avanzare la stessa iteratore in una linea per andare al prossimo elemento?

Sì, è valido.


Rationale:

it++ incrementi it cosicché si riferisca all'elemento successivo, ma produce una copia del suo valore originale . Pertanto, it non fa riferimento all'elemento rimosso quando viene chiamato erase(). E in caso di std::set solo gli iteratori dell'elemento cancellato sono invalidati. # 1

È possibile considerare questo esempio di codice come codice di riferimento per rimuovere un elemento a cui si riferisce il proprio iteratore.


Riferimenti:

Per std::set,
# 1C++ 03 standard 23.1.2/8:

Solo Iteratori e riferimenti alla cancellata gli elementi sono invalidati

2

Sì, è valido. L'espressione it++ viene valutata completamente prima di chiamare la funzione, quindi la funzione riceve il valore precedente di it, ma nel momento in cui viene rimosso (e invalidato), l'iteratore è già stato incrementato.