This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of CD1 status.
Section: 24.3.2.3 [iterator.traits] Status: CD1 Submitter: Dave Abrahams Opened: 2003-12-09 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [iterator.traits].
View all issues with CD1 status.
Discussion:
The standard places no restrictions at all on the reference type of input, output, or forward iterators (for forward iterators it only specifies that *x must be value_type& and doesn't mention the reference type). Bidirectional iterators' reference type is restricted only by implication, since the base iterator's reference type is used as the return type of reverse_iterator's operator*, which must be T& in order to be a conforming forward iterator.
Here's what I think we ought to be able to expect from an input or forward iterator's reference type R, where a is an iterator and V is its value_type
A mutable forward iterator ought to satisfy, for x of type V:
{ R r = *a; r = x; } is equivalent to *a = x;
I think these requirements capture existing container iterators (including vector<bool>'s), but render istream_iterator invalid; its reference type would have to be changed to a constant reference.
(Jeremy Siek) During the discussion in Sydney, it was felt that a
simpler long term solution for this was needed. The solution proposed
was to require reference
to be the same type as *a
and pointer
to be the same type as a->
. Most
iterators in the Standard Library already meet this requirement. Some
iterators are output iterators, and do not need to meet the
requirement, and others are only specified through the general
iterator requirements (which will change with this resolution). The
sole case where there is an explicit definition of the reference type
that will need to change is istreambuf_iterator
which returns
charT
from operator*
but has a reference type of
charT&
. We propose changing the reference type of
istreambuf_iterator
to charT
.
The other option for resolving the issue with pointer
,
mentioned in the note below, is to remove pointer
altogether. I prefer placing requirements on pointer
to
removing it for two reasons. First, pointer
will become
useful for implementing iterator adaptors and in particular,
reverse_iterator
will become more well defined. Second,
removing pointer
is a rather drastic and publicly-visible
action to take.
The proposed resolution technically enlarges the requirements for
iterators, which means there are existing iterators (such as
istreambuf_iterator
, and potentially some programmer-defined
iterators) that will no longer meet the requirements. Will this break
existing code? The scenario in which it would is if an algorithm
implementation (say in the Standard Library) is changed to rely on
iterator_traits::reference
, and then is used with one of the
iterators that do not have an appropriately defined
iterator_traits::reference
.
The proposed resolution makes one other subtle change. Previously,
it was required that output iterators have a difference_type
and value_type
of void
, which means that a forward
iterator could not be an output iterator. This is clearly a mistake,
so I've changed the wording to say that those types may be
void
.
Proposed resolution:
In 24.3.2.3 [iterator.traits], after:
be defined as the iterator's difference type, value type and iterator category, respectively.
add
In addition, the types
iterator_traits<Iterator>::reference iterator_traits<Iterator>::pointermust be defined as the iterator's reference and pointer types, that is, the same type as the type of
*a
anda->
, respectively.
In 24.3.2.3 [iterator.traits], change:
In the case of an output iterator, the types
iterator_traits<Iterator>::difference_type iterator_traits<Iterator>::value_typeare both defined as
void
.
to:
In the case of an output iterator, the types
iterator_traits<Iterator>::difference_type iterator_traits<Iterator>::value_type iterator_traits<Iterator>::reference iterator_traits<Iterator>::pointermay be defined as
void
.
In 24.6.4 [istreambuf.iterator], change:
typename traits::off_type, charT*, charT&>
to:
typename traits::off_type, charT*, charT>
[ Redmond: there was concern in Sydney that this might not be the only place where things were underspecified and needed to be changed. Jeremy reviewed iterators in the standard and confirmed that nothing else needed to be changed. ]