Search code examples
c++c++11iteratorstdmapconst-iterator

Why const_iterator could be used with std::map::erase


I was under the impression one cant use erase on a const iterator. Check this code.
Why does the below code compile (C++11, gcc)?

long getMax(const bool get_new)
{
    long max_val=0;

    TO now=getNow();

    map<TO, long>& m=get_new?m_new:m_old;

    for(auto it=m.cbegin(); it !=m.cend())
    {
        if(now.compareTime((*it).first)<lookback)
        {
            max_val=max(max_val,
                        (*it).second);
            ++it;
        }
        else
        {
            it=m.erase(it);
        }
    }

    return max_val;
}

The map itself is not constant, but my understanding is that the const iterator should make this fail.


Solution

  • The behavior has changed from C++11; std::map::erase takes const_iterator as its parameter.

    void erase( iterator pos );           // (until C++11)
    iterator erase( const_iterator pos ); // (since C++11)
    iterator erase( iterator pos );       // (since C++17)
    

    For std::map::erase, the passed iterator is just used as the position where the element would be deleted, not for modifying the element through it. That means const_iterator would be fine. Before C++11, the support for const_iterator was not very good, but the situation has changed from C++11. You should use const_iterator instead of iterator when possible now.