Read-Only Iterators
In our CheckList
class—which used pointers as iterators—we declared two different begin/end functions:
// We provide two overloaded begin/end functions: one for writable checklists
// and one for read-only ones.
std::string* begin();
std::string* end();
const std::string* begin() const;
const std::string* end() const;
What should std::list<double>
do if the list is read-only? Would it be okay to return a const std::list<double>::iterator
?
C++'s solution is to provide two distinct classes that are almost identical, the only difference being whether operator*
returns a reference or a const
reference. So
std::list<double>::iterator
is an iterator that lets you write the data (and read it, too).std::list<double>::const_iterator
is an iterator that only lets you read the data.
All the C++ standard-library data structures work similarly, with two types, an iterator
type and a const_iterator
type.
So a
const iterator
is not the same as aconst_iterator
?That's right.
Whee.
…
One positive thing about using auto i = myList.begin()
is that you don't have to worry about what the right type to write for a particular situation, C++ will automatically pick the right type. So, when we aren't allowed to write to the data, we'll have a const_iterator
, and otherwise we'll get an iterator
back.
Wait, what? How?
It's a bit of a hack, but the
begin()
function is overloaded to return a different type depending on whether the object isconst
or not.So if
myList
isconst
,myList.begin()
returns aconst_iterator
, and ifmyList
is notconst
,myList.begin()
returns aniterator
.I'm not sure I like this. Two
begin()
functions? That seems confusing.It's not ideal, but it's the best we can do. We need to be able to return a different type depending on whether
myList
isconst
or not, and this is the only way to do it.Guess you can't blame C for this one.
(When logged in, completion status appears here.)