2012-01-23 4 views
6

Czy można poprawnie przejść przez QMap za pomocą iteratorów i wykonywać takie czynności: usuwanie niektórych elementów i dodawanie nowych?Czy można przejść przez QMap z iteratorami i kasowaniem/dodawaniem przedmiotów?

Na przykład:

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); 
    } 
} 

Wydaje się, że nic nie zostanie zrobione źle, pytam się upewnić. (Nie mam dość czasu, żeby to sprawdzić).

UPD rozwiąże z 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); 

Dzięki za odpowiedzi!

Odpowiedz

4

Zastanówcie się przez chwilę ... Wykonujecie iterację nad kolekcją, usuwając przedmiot w środku i dodając kolejny element gdzie indziej. Czy iteratory będą nadal poprawne? Czy "następny" iterator będzie naprawdę kolejnym elementem?

Generalnie nie jest dobrym pomysłem zmienić kolekcję, którą przeglądasz. Jeśli musisz wtedy użyć kolekcji tymczasowej i skopiować wybrane elementy, wyczyść prawdziwą kolekcję i przenieś elementy z kolekcji tymczasowej do rzeczywistej.

W twoim przypadku jednak, dlaczego nie wykorzystać QMap::find szukać something, i jeśli znajdzie go usunąć i dodać nowy element, i zrobić to w pętli aż something nie znajduje już?

+0

Dziękujemy za przydatną odpowiedź! Nie mogę użyć twojej rady w ostatnim zdaniu, ponieważ powinienem manipulować pozycją QMap szukającą jej wartości. Po usunięciu i wstawieniu wartości nie zmienia się, więc mogę operować z tymi samymi obiektami w nieskończoność. Wziąłem pod uwagę twoją radę, aby użyć kolekcji tymczasowej i rozwiązać problem z QMap :: unite(). Bardzo dziękuję! – ASten

1

Musisz "zresetować" swój iterator do tego, który został zwrócony przez erase i insert. Zasadniczo jest w porządku.

2

Spodziewam się, że it będzie nieważny po map.erase(it), w którym to przypadku it->value i ++it nie będą działać.

13

Iterator zostanie unieważniony przez erase, więc nie można go bezpiecznie używać ani później zwiększać. Powinny działać następujące:

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

Czuję, że to jest poprawna odpowiedź. –