Search code examples
c++stdmap

Cannot increment value-initialized map/set iterator


I'm trying to increment key of nodes after the index j in a map, but I got some error while incrementing the iterator to the next node, here's my code :

typedef map<int, string> My_map;    
My_map my_map;
my_map[0] = "la base";
my_map[1] = "le premier";

int j = 1;

My_map::reverse_iterator first_it(my_map.rbegin());
first_it++;
My_map::reverse_iterator last_it(make_reverse_iterator(next(my_map.begin(), j - 1)));

for (My_map::reverse_iterator it = first_it ; it != last_it ; it++) {
    auto handle = my_map.extract(it.base());
    handle.key()++;
    my_map.insert(move(handle));
}

I know that a map cannot have duplicate keys, so I started incrementing from the last one to the j-th one. But the it++ does not work. Is it different from when I used first_it++; ?


Solution

  • In the documentation for std::map::extract it mentions the side-effects:

    Extracting a node invalidates only the iterators to the extracted element. Pointers and references to the extracted element remain valid, but cannot be used while element is owned by a node handle: they become usable if the element is inserted into a container.

    As you can see, all the iterators are find except for the ones you care about. Because it is an iterator to the extracted element, it is now invalid. Subsequent attempts to use it (with it++ to advance the loop iteration) leads to undefined behavior.

    What you can do is use the iterator returned by std::map::insert:

    auto result = my_map.insert(move(handle));
    it = make_reverse_iterator(result.position);