Search code examples
c++multimap

How do I remove a specific item from my multimap?


#include <map>
#include <iostream>
 
int main()
{
    std::multimap <int, int> map;
 
    // insert the values in multimap
    map.insert(std::make_pair(1, 10));
    map.insert(std::make_pair(2, 20));
    map.insert(std::make_pair(2, 30));
    map.insert(std::make_pair(2, 40));
    map.insert(std::make_pair(3, 50));
    map.insert(std::make_pair(4, 60));
    map.insert(std::make_pair(4, 70));
     
    int key = 2;   
    bool fo = false;
    for (auto itr = map.begin(); itr != map.end(); itr++)   
    {
      if (itr -> first == key)       
      {  
        if(fo)
        {
          map.erase(itr);
        }
        fo = true;
      }
    }

     for (auto itr = map.begin(); itr != map.end(); itr++)   
     {
                std::cout << itr -> first << "  "
                 << itr -> second << std::endl;
     }

    return 0;
}

The map.erase(itr); is making the last for loop output nothing. The idea is that the last for loop will output my map without the 2s, with the exception of the first 2 because of my bool fo. How can I fix this as to get the desired output I described above?


Solution

  • map.erase(itr);
    

    The itr iterator is now invalid. When you erase() something from the container, the iterator for the erased value is always invalidated, and depending on the container other iterators may or may not be invalidated. But the issue here is this particular itr. It is now a flaming wreckage.

    ...; itr++)
    

    ... aaaand immediately afterwards this increments invalid iterator. Hillarity ensues.

    If you check erase() documentation you will discover that erase() returns the iterator to the next value in the container, what itr++ would've returned. Therefore, the correct approach for something like this

    if ( ... your condition goes here ... )
    {
        itr=map.erase(itr);
    }
    else
    {
        itr++;
    }
    

    And the increment of the iterator is removed from the for loop itself, and done here, as an alernative to erase().