问题
Why do const
STL containers only return const_iterator
s?
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>
回答1:
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_iterator
s.
回答2:
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
}
来源:https://stackoverflow.com/questions/30924328/does-const-containers-have-only-const-iterator