Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it correct to walk through QMap with iterators and erasing/adding items?

Tags:

c++

iterator

qt

Is it correctly possible to walk sequently through QMap with help of iterators, and doing such actions: removing some items and adding new ones?

For example:

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

It seems, that nothing will be done wrong, I'm asking to be sure. (I have no enough time to check it).

UPD Will solve with 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);

Thanks for answers!

like image 738
ASten Avatar asked Jan 23 '12 14:01

ASten


4 Answers

The iterator will be invalidated by erase, and so cannot safely be used or incremented afterwards. The following should work:

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;
    }
}
like image 92
Mike Seymour Avatar answered Oct 20 '22 17:10

Mike Seymour


Think about it a little while... You are iterating over a collection, removing an item in the middle and adding another item somewhere else. Will the iterators still be correct? Will the "next" iterator really be the next item?

In general it is not a good idea to change a collection you are iterating over. If you need to then use a temporary collection and copy selected items over to that, and clear the real collection and move the items from the temporary collection over to the real one.

In your case though, why not use QMap::find to search for something, and if found erase it and add the new item, and do it in a loop until something is not found anymore?

like image 20
Some programmer dude Avatar answered Oct 20 '22 18:10

Some programmer dude


I would expect it to be invalid after map.erase(it), in which case it->value and ++it will not work.

like image 29
Bo Persson Avatar answered Oct 20 '22 18:10

Bo Persson


You have to 'reset' your iterator to the one returned by erase and insert. It's fine in principle though.

like image 26
cmannett85 Avatar answered Oct 20 '22 18:10

cmannett85