Does const containers have only const iterator?

1.2k views Asked by At

Why do const STL containers only return const_iterators?

For example both std::vector and std::list have the method begin overloaded as:

iterator begin();
const_iterator begin() const;
const_iterator cbegin() const;

I thought I could still modify values of a const vector but not the vector itself. According to the standard library there is no difference between:

const std::vector<int>

and

const std::vector<const int>
2

There are 2 answers

2
vsoftco On BEST ANSWER

Suppose you have

iterator begin() const;

instead of

const_iterator begin() const;

Now, think what happens when you have

const vector<Foo> v;

You will be able to do something like

*v.begin() = other_foo;

which of course shouldn't be legal if you want to preserve logical const-ness. The solution is therefore to make the return type const_iterator whenever you invoke iterators on const instances.

The situation is similar to having const classes that have pointer members. In those cases, you may modify the data the pointer points to (but not the pointer itself), so logical const-ness is not preserved. The standard library took a step forward and disallowed these kind of modifications on standard containers via const overloads that return const_iterators.

1
Cory Kramer On

If you declare your vector as

const std::vector<int> foo;

Then the vector itself is const, meaning you cannot push_back, erase, etc. However, you can modify its elements

for (std::vector<int>::iterator it = foo.begin(); it != foo.end(); ++it)
{
    int& x = *it;
    x++;           // This is fine!
}

When you iterate over a vector, you are enforcing that the elements of the vector are const. So you can modify the vector by adding and removing things, but you may not modify the actual elements.

std::vector<Foo> values;  // Neither the vector nor its elements are const

for (std::vector<Foo>::const_iterator it = values.cbegin(), it != values.cend(); ++it)
{
    Foo const& foo = *it;         // I may not try to modify foo
    it->CallToNonConstMethod();   // Can't do this either
}