Calling erase with iterator vs const_iterator

This doesn’t compile because container::iterator and container::const_iterator are two distinct types and the only (one-argument) version of erase is: iterator erase(iterator);

Not accepting a const_iterator can be viewed as a defect in the language standard: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2350.pdf

There is no particular reason for this restriction. The iterator is only used to indicate a position in the (modifiable) container, and neither in case of insert or erase is the “pointee” of the iterator modified (in case of erase it just conceptually goes out of existence, which is a normal thing to do for const objects).

Current standard indicates a confusion between “iterator constness and container constness” (as do other answers here), and it seems const_iterator might become acceptable for erase in C++0x.


As a workaround, you can validly obtain an iterator from a const_iterator because the container has to be mutable in the first place.

The function below is only compilable for random access iterators, as it might be a bit too slow to do this with other types of iterators.

#include <vector>

template <class Container>
typename Container::iterator to_mutable_iterator(Container& c, typename Container::const_iterator it)
{
    return c.begin() + (it - c.begin());
}

int main()
{
    int arr[] = {1, 5, 2, 5, 3, 4, 5, 1};
    std::vector<int> vec(arr, arr + sizeof(arr) / sizeof(*arr));
    for (std::vector<int>::const_iterator it = vec.begin(); it != vec.end(); ) {
        //if (*it = 5) {  //const_iterator prevents this error
        if (*it == 5) {
            it = vec.erase(to_mutable_iterator(vec, it));
        }
        else {
            ++it;
        }
    }
}

However, it might be better to restructure code so that you don’t need a const_iterator in the first place. In this case, it would be better to use the std::remove algorithm. If you need to do more non-mutating work before erasing, you can extract that into a separate method etc.

Leave a Comment