Topic: Type of value returned by dereferencing an iterator


Author: Adam Badura <abadura@o2.pl>
Date: Tue, 16 Nov 2010 22:26:40 CST
Raw View
Type returned by dereferencing an iterator it its
iterator_traits::reference type, is it?

But is is required to be actually a (const/mutable) reference to the
value type of the iterator? Or can it be a wrapper which behaves like
it were a reference. The Standard (both current and future) doesn't
seem to be explicit enough about it (or at least not enough for me).

Also I wonder whether there are any restrictions put on how long the
value returned by dereferencing an iterator remains valid (in terms of
iterator operations). It seems justifiable that if the iterator is
moved or invalidated (by operation on its container) then the returned
value is no longer valid. It also seems a safe assumption. But is it
required to be so? Or maybe the returned value (returned by
dereferencing) may remain valid only for the time of the expression in
which it appears?


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Thu, 18 Nov 2010 10:12:15 CST
Raw View
On 17.11.2010 05:26, Adam Badura wrote:
>
> Type returned by dereferencing an iterator it its
> iterator_traits::reference type, is it?
>
> But is is required to be actually a (const/mutable) reference to the
> value type of the iterator? Or can it be a wrapper which behaves like
> it were a reference. The Standard (both current and future) doesn't
> seem to be explicit enough about it (or at least not enough for me).

The current state for C++0x is, that the requirements of
iterator_traits<X>::reference type for a type X satisfying the new
Iterator requirements is unspecified, for a type X satisfying the
Input Iterator requirements is

std::is_convertible<iterator_traits<X>::reference,
                   iterator_traits<X>::value_type>::value == true

and for any refinement of a Forward Iterator is
"iterator_traits<X>::value_type&" for mutable iterators and "const
iterator_traits<X>::value_type&" for const iterators. For a pure
output iterator, iterator_traits<X>::reference may be void, because
there is no isolated access to the expression *it and it may have more
than one value types that can be assigned to.

IMO this can be clearly read from the iterator requirement tables and
from the specification of iterator_traits (for output iterator).

It is very unfortunate that C++0x was not able to completely refactor
the iterator concepts. A cleaner approach would have been to separate
traversal and access criteria. IMO this is one necessary step for the
next revision of the C++ Library.

> Also I wonder whether there are any restrictions put on how long the
> value returned by dereferencing an iterator remains valid (in terms of
> iterator operations). It seems justifiable that if the iterator is
> moved or invalidated (by operation on its container) then the returned
> value is no longer valid. It also seems a safe assumption. But is it
> required to be so? Or maybe the returned value (returned by
> dereferencing) may remain valid only for the time of the expression in
> which it appears?

Since an input iterator may just copy the "referenced" value during an
attempt to dereference, there cannot much be argued about validity,
because the query must be assumed to get a copy that has the life-time
rules of a local object of automatic storage.

For any iterator refining the forward iterator requirements the
reference must be valid unless the iterator becomes invalid, this
This is only an indirect requirement which results from the sum of
those listed in 24.2.5/6. Currently, the rules when an iterator may
become invalid, is only diffusely described and was the reason for LWG
issue 1213, see

http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1213

In absence of this clarification, it can quite reasonably be argued that
it depends on other operations acting on the underlying sequence. E.g.
if it is a container the container requirements desceribe under which
conditions an iterator becomes invalid. For any non-container
sequence, the validity of the referenced object completely completely
depends on the operations that would invalidate the sequence that the
corresponding iterator value is pointing to, etc.

HTH & Greetings from Bremen,

Daniel Kr   gler


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]