[cfe-dev] const correctness of iterator methods

Sebastian Redl sebastian.redl at getdesigned.at
Wed Jun 26 16:09:15 PDT 2013


On 27.06.2013, at 00:38, Shriramana Sharma wrote:

> Hi -- again a few questions about the libc++ container templates.
> 
> I note that __list_iterator::operator*() returns a non-const reference
> but is marked as const. The operator-> next to it returns a non-const
> pointer but is also marked const. OTOH in the list class, the begin()
> and end() methods returning non-const iterators are NOT marked const
> and only those returning const iterators are marked const.

Note that none of this is in any way particular to libc++; that's how the standard specifies these things to work.

> 
> I thought a method should be const if it does not modify the contents
> of the object by itself, and not based on whether the value it returns
> could be used to modify the object.

This is an oversimplification that is leading you astray.

The correct rule is, "a const method should not give the caller a way of modifying the logical state of the object". What is part of the logical state and what is not is the class designer's decision.

The logical state of an iterator is "I point at some element of a sequence". The value of that element is not part of its logical state. Therefore, operator* and operator-> are const: they only allow changing the value of the element pointed at, not what element the iterator points at.

The logical state of a container is "all the logical states of my elements". Modifying an element's logical state is thus a modification of the container's logical state. Therefore, the versions of begin() and end() that return non-const iterators cannot be const, since they offer a way to modify the container's logical state.

Does that make sense?

Sebastian



More information about the cfe-dev mailing list