Правильно ли проходить через QMap с итераторами и стирать / добавлять элементы? - PullRequest
6 голосов
/ 23 января 2012

Можно ли правильно последовательно проходить через QMap с помощью итераторов и выполнять такие действия: удаление некоторых элементов и добавление новых?

Например:

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

Кажется, что ничего не будет сделано неправильно, я прошу быть уверенным. (У меня нет достаточно времени, чтобы проверить это).

UPD Будет решать с 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);

Спасибо за ответы!

Ответы [ 4 ]

14 голосов
/ 23 января 2012

Итератор будет признан недействительным на erase, поэтому его нельзя безопасно использовать или увеличивать впоследствии. Должно работать следующее:

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;
    }
}
4 голосов
/ 23 января 2012

Подумайте об этом немного ... Вы перебираете коллекцию, удаляете элемент посередине и добавляете другой элемент в другое место. Будут ли итераторы правильными? Будет ли «следующий» итератор следующим элементом?

В общем случае не стоит менять коллекцию, для которой вы выполняете итерацию. Если вам необходимо использовать временную коллекцию, скопировать в нее выбранные элементы, очистить реальную коллекцию и переместить элементы из временной коллекции в реальную.

В вашем случае, однако, почему бы не использовать QMap::find для поиска something, а если он найден, стереть его и добавить новый элемент, и делать это в цикле, пока something больше не будет найден?

2 голосов
/ 23 января 2012

Я ожидаю, что it будет недействительным после map.erase(it), в этом случае it->value и ++it не будут работать.

1 голос
/ 23 января 2012

Вы должны «сбросить» свой итератор на тот, который возвращали erase и insert.Хотя в принципе все нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...