2012-01-23 16 views
6

È possibile camminare in modo sequenziale attraverso QMap con l'aiuto degli iteratori e compiere tali azioni: rimuovere alcuni elementi e aggiungerne di nuovi?È corretto percorrere QMap con iteratori e cancellare/aggiungere elementi?

Ad esempio:

for(QMap<key_t,val_t>::iterator it = map.begin(); 
    it != map.end(); 
    ++it) 
{ 
    if(it->value == something) 
    { 
      map.erase(it); 
      map.insert(it->key+10,it->value); 
    } 
} 

Sembra, che nulla sarà fatto male, sto chiedendo di essere sicuri. (Non ho abbastanza tempo per controllarlo).

UPD risolveremo con QMap::unite():

for(QMap<key_t,val_t>::iterator it = map.begin(); 
    it != map.end(); 
    ++it) 
{ 
    if(it->value == something) 
    { 
      tmp_map.insert(it->key+10,it->value); 
      map.erase(it); 
    } 
} 
map.unite(tmp_map); 

Grazie per le risposte!

risposta

4

Pensaci un po '... Stai iterando su una raccolta, rimuovendo un oggetto nel mezzo e aggiungendo un altro elemento da qualche altra parte. Gli iteratori continueranno a essere corretti? Il prossimo "iteratore" sarà davvero il prossimo oggetto?

In generale non è una buona idea cambiare una raccolta su cui si sta iterando. Se è necessario quindi utilizzare una raccolta temporanea e copiare gli elementi selezionati oltre a quello, e deselezionare la raccolta reale e spostare gli elementi dalla raccolta temporanea a quella reale.

Nel tuo caso, però, perché non utilizzare QMap::find per cercare something, e se trovato cancellare e aggiungere il nuovo elemento, e lo fa in un ciclo fino something non si trova più?

+0

Grazie per la risposta utile! Non posso usare il tuo consiglio nell'ultima frase perché dovrei manipolare con item di QMap cercando il suo valore. Dopo aver cancellato e inserito il valore non cambia, quindi posso operare infinitamente con gli stessi oggetti. Ho preso in considerazione il tuo consiglio per utilizzare una raccolta temporanea e risolvere il problema con QMap :: unite(). Grazie mille! – ASten

1

È necessario reimpostare l'iteratore su quello restituito da erase e insert. In linea di principio, comunque.

2

Mi aspetto che it non sia valido dopo map.erase(it), nel qual caso it->value e ++it non funzionerà.

13

L'iteratore verrà invalidato da erase e pertanto non può essere utilizzato in modo sicuro o incrementato in seguito. Il seguente dovrebbe funzionare:

for(QMap<key_t,val_t>::iterator it = map.begin(); it != map.end();) 
{ 
    if(it->value == something) 
    { 
     map.insert(it.key()+10,it.value()); 
     it = map.erase(it); 
    } else { 
     ++it; 
    } 
} 
+0

Sento che questa è la risposta corretta. –

Problemi correlati