views:

1804

answers:

5

What is the difference between a ::const_iterator and an ::iterator and where would you use one over the other?

+17  A: 

const_iterators don't allow you to change the values that they point to, regular iterators do.

As with all things in C++, always prefer const, unless there's a good reason to use regular iterators (i.e. you want to use the fact that they're not const to change the pointed-to value).

Dominic Rodger
In a perfect world that would be the case. But with C++ const is only as good as the person who wrote the code :(
JaredPar
mutable exists for a very good reason. It is rarely used, and looking at Google Code Search, there appears to be fair percentage of valid uses. The keyword is a very powerful optimization tool, and it's not like removing it would improve const-correctness(*coughpointerscoughandcoughreferencescough*)
coppro
More like a powerful hack. Of all the instances I have ever seen of the use of the 'mutable' keyword, all but one was an accurate indicator that the code was poorly written and mutable was needed as a hack to get around the defects.
John Dibling
It does have legitimate uses, like caching the results of a long calculation within a const class. On the other hand, that's pretty much the only time I've used a mutable in nearly twenty years of C++ development.
Head Geek
+5  A: 

They should pretty much be self-explanatory. If iterator points to an element of type T, then const_iterator points to an element of type 'const T'.

It's basically equivalent to the pointer types:

T* // A non-const iterator to a non-const element. Corresponds to std::vector<T>::iterator
T* const // A const iterator to a non-const element. Corresponds to const std::vector<T>::iterator
const T* // A non-const iterator to a const element. Corresponds to std::vector<T>::const_iterator

A const iterator always points to the same element, so the iterator itself is const. But the element it points to does not have to be const, so the element it points to can be changed. A const_iterator is an iterator that points to a const element, so while the iterator itself can be updated (incremented or decremented, for example), the element it points to can not be changed.

jalf
"A const iterator always points to the same element," This is incorrect.
John Dibling
How so? Note the missing underscore. I'm contrasting a variable of type const std::vector<T>::iterator with std::vector<T>::const_iterator.In the former case, the iterator itself is const, so it can't be modified, but the element it references can be modified freely.
jalf
Ah, I see. Yes I missed the missing underscore.
John Dibling
+1  A: 

Use const_iterator whenever you can, use iterator when you have no other choice.

Naveen
A: 

(as others have said) const_iterator doesn't allow you modify the elements to which it points, this is useful inside of const class methods. It also allows you to express your intent.

Trey Jackson
+1  A: 

Unfortunaty, a lot of the methods for the STL containers takes iterators instead of const_iterators as parameters. So if you have a const_iterator, you can't say "insert an element before the element that this iterator points to" (saying such a thing is not conceptually a const violation, in my opinion). If you want do that anyway, you have to convert it to a non-const iterator using std::advance() or boost::next(). Eg. boost::next(container.begin(), std::distance(container.begin(), the_const_iterator_we_want_to_unconst)). If container is a std::list, then the running time for that call will be O(n).

So the universal rule to add const wherever it is "logical" to do so, is less universal when it comes to STL containers.