Erase/Remove contents from the map (or any other STL container) while iterating it

前端 未结 9 1326
无人及你
无人及你 2020-12-01 07:55

Allegedly you cannot just erase/remove an element in a container while iterating as iterator becomes invalid. What are the (safe) ways to remove the elements that meet a cer

相关标签:
9条回答
  • 2020-12-01 08:33

    markh44 is the most STL-ish response. Note, however, that in general, iterators are invalidated by modifying the container, but set and map are exceptions. There, you can remove items and still go on using the iterators, except if you delete the very item your iterator is referencing.

    0 讨论(0)
  • 2020-12-01 08:43

    Viktor's solution has the upside of being able to do something with the element before removing. (I wasn't able to do this with remove_if or remove_copy_if.) But I prefer to use std::find_if so I never have to increment the iterator myself:

    typedef vector<int> int_vector;
    int_vector v;
    
    int_vector::iterator itr = v.begin();
    for(;;)
    {
        itr = std::find_if(itr, v.end(), Predicate(4));
        if (itr == v.end())
        {
            break;
        }
    
        // do stuff with *itr here
    
        itr = v.erase(itr);  // grab a new, valid iterator
    }
    

    Where Predicate could be bind1st( equal_to<int>(), 4 ) or something like this:

    struct Predicate : public unary_function<int, bool>
    {
        int mExpected;
        Predicate(int desired) : mExpected(desired) {}
        bool operator() (int input)
        {
            return ( input == mExpected );
        }
    };
    
    0 讨论(0)
  • 2020-12-01 08:45

    1.For std::vector<> :

    std::vector <int> vec;
    vec.erase(std::remove(vec.begin(),vec.end(), elem_to_remove), vec.end());
    

    2.For std::map<> always use std::map::erase()

    std::map<int,std::string> myMap;
    myMap.emplace(std::make_pair(1, "Hello"));
    myMap.emplace(std::make_pair(2, "Hi"));
    myMap.emplace(std::make_pair(3, "How"));
    myMap.erase( 1);//Erase with key
    myMap.erase(myMap.begin(), ++myMap.begin() );//Erase with range
    for( auto &ele: myMap)
    {
        if(ele.first ==1)
        {
            myMap.erase(ele.first);//erase by key 
            break; //You can't use ele again properly 
                   //wthin this iteration, so break.
        }
    }
    
    1. For std::list use std::list::erase()
    0 讨论(0)
提交回复
热议问题