CS 70

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?

Is a const std::list<double>::iterator the right thing to return?

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.

  • Goat speaking

    So a const iterator is not the same as a const_iterator?

  • LHS Cow speaking

    That's right.

  • Goat speaking

    Whee.

  • Hedgehog speaking

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.

  • Duck speaking

    Wait, what? How?

  • Bjarne speaking

    It's a bit of a hack, but the begin() function is overloaded to return a different type depending on whether the object is const or not.

  • LHS Cow speaking

    So if myList is const, myList.begin() returns a const_iterator, and if myList is not const, myList.begin() returns an iterator.

  • Hedgehog speaking

    I'm not sure I like this. Two begin() functions? That seems confusing.

  • Bjarne speaking

    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 is const or not, and this is the only way to do it.

  • Goat speaking

    Guess you can't blame C for this one.

(When logged in, completion status appears here.)