const correctness of iterator methods

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

const correctness of iterator methods

Shriramana Sharma
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.

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. In this case, it is correct to
mark the iterator's operators * and -> as const because they
themselves do not modify the contents of the list, although their
return value could definitely be used for that. But why is then
begin() returning a non-const iterator NOT marked as const, given that
it itself doesn't modify the contents of the list in any way?

Thanks!

--
Shriramana Sharma ஶ்ரீரமணஶர்மா श्रीरमणशर्मा

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: const correctness of iterator methods

Sebastian Redl

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
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev