The std::iterator_traits
class template defines 5 nested types: iterator_category
, value_type
, difference_type
, pointer
and reference
. Browsing the sources of the <algorithm>
header of both libc++ and libstdc++, one can see many uses of value_type
, difference_type
and iterator_category
, but only one for reference
(inside std::iter_swap
) and none for pointer
.
My application uses a hand-built proxy iterator / proxy reference pair. I want to transition to using the Boost iterator_facade
which lets me configure the reference type from the default T&
to an arbitrary type, but not so for the pointer type which is T*
by default. I want to avoid being bitten by some deeply hidden use of the nested pointer
type.
Note: the iterator is a proxy for a builtin type without nested members, so I do not need compatibility with operator->
(for which the return type would be pointer
).
Question: what use cases are there in the Standard Library for the nested type pointer
inside iterator_traits
?
In contrast to the first three types iterator_category
, value_type
and difference_type
(which are heavily used by the standard algorithms for tag dispatching to efficient versions depending on the iterator capabilities) the last two types pointer
and reference
inside iterator_traits
appear not to be used by any algorithms but are used to define compliance with the iterator requirements.
24.2.1 In general [iterator.requirements.general]
1 [..] All iterators
i
for which the expression(*i).m
is well-defined, support the expressioni->m
with the same semantics as(*i).m
. [...]
24.4.1 Iterator traits [iterator.traits]
[...] In addition, the types
iterator_traits<Iterator>::reference iterator_traits<Iterator>::pointer
shall be defined as the iterator’s reference and pointer types, that is, for an iterator object
a
, the same type as the type of*a
anda->
, respectively. [...]
The default values T*
and T&
for pointer
and reference
of course satisfy the iterator requirements. Regarding proxy references, the Boost.Iterator documentation specifies
The
reference
type of a readable iterator (and today's input iterator) need not in fact be a reference, so long as it is convertible to the iterator'svalue_type
. When thevalue_type
is a class, however, it must still be possible to access members throughoperator->
. Therefore, an iterator whosereference
type is not in fact a reference must return a proxy containing a copy of the referenced value from itsoperator->
.The return types for
iterator_facade
'soperator->
andoperator[]
are not explicitly specified. Instead, those types are described in terms of a set of requirements, which must be satisfied by theiterator_facade
implementation.
Conclusion: as long as a proxy iterator does not require accessing members of its underlying value_type
through .m
or ->m
, one does not need to worry about the pointer
type inside iterator_traits
, and even if one does use proxy iterators, boost::iterator_facade
will do the right thing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With