[lug] OT: C++ question, const_iterator design

D. Stimits stimits at attbi.com
Sun Jun 1 00:14:55 MDT 2003

No matter where I go, I can't seem to find an answer to this.

In most STL container templates, there is a const and a non-const 
version of "begin()" iterator methods. They are declared like this:
iterator begin();
const_iterator begin() const;

This is NOT a case of iterator being derived from const_iterator, they 
are separate classes. The method "foo()" differs in function signature 
because "foo() const" is different than "foo()". In simple examples I've 
seen, iterator and const_iterator do not share anything at all, and in 
Redhat 7.3 and 8.0 (I'm using multimap, since it is closest to the 
container I'm writing), they share a common base, but they are siblings, 
NOT one derived from the other. There is no implicit conversion between 
these iterators, the const_iterator can be initialized with a volatile 
iterator only because the functionality to do so has been explicitly 

These iterators can be used like this:
iterator it_non_const = foo.begin();
const_iterator it_const = foo.begin();

I'm not dealing with a simple pointer iterator, I'm dealing with an 
iterator for a custom container that gets rather complicated, and 
requires iterator and const_iterator to be full classes (books tend to 
use an alias to a pointer/array type for their contrived examples). I 
have defined in the container:
iterator begin():
const_iterator begin() const;

I have a class iterator with operator= and a class const_iterator with 
operator=. The operator= for iterator takes argument (const iterator), 
and the argument for operator= in const_iterator is (const 
const_iterator). When I do this it works:
iterator it_non_const = foo.begin();

When I do this, it fails:
const_iterator it_const = foo.begin();

I can show that my const_iterator operator= code it is trying to call 
the non-const foo.begin(), but the STL in RH 7.3 and 8.0 correctly call 
the const begin() in theirs. Why does this work for RH's STL, but not 
for me? What must be done with the "operator=(const const_iterator)" to 
force it to use the const signature version "const_iterator begin() 
const" (rather than complain that it has no way to convert from a 
non-const iterator via operator=)? Is there some arcane syntax, such as 
with pre-decrement and pre-increment operator overloads (e.g., 
"operator++(int)")? From the RH 7.3 and 8.0 STL files, I have not yet 
figured out how to do this without deriving iterator from 
const_iterator, or via a type conversion...yet I am 100% positive that 
no type conversion is going on with the STL versions.

D. Stimits, stimits AT attbi DOT com

More information about the LUG mailing list