c++algorithmstldictionarycontainers

Erase specific elements in std::map


I want to erase some elements in my std::map.
I wrote erase + remove_if technique which I always do with other sequence containers.
But it wasn't compile with map. Why?
And How can I do this job?

std::map<int, int> m;

bool foo(const std::pair<int, int>& p)
{
    return p.second > 15;
}

int _tmain(int argc, _TCHAR* argv[])
{
    m.insert(make_pair(0, 0));
    m.insert(make_pair(1, 10));
    m.insert(make_pair(2, 20));
    m.insert(make_pair(3, 30));

    m.erase(
        remove_if(m.begin(), m.end(), foo),
        m.end()); // compile error

    return 0;
}

Solution

  • Write it like this for map, since remove_if won't work for map iterators (it merely puts offending elements at the end, and map iterators don't allow for this):

    template <typename Map, typename F>
    void map_erase_if(Map& m, F pred)
    {
        typename Map::iterator i = m.begin();
        while ((i = std::find_if(i, m.end(), pred)) != m.end())
            m.erase(i++);
    }
    

    or if you like one-liners:

    template <typename Map, typename F>
    void map_erase_if(Map& m, F pred)
    {
        for (typename Map::iterator i = m.begin();
             (i = std::find_if(i, m.end(), pred)) != m.end();
             m.erase(i++));
    }