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
ifor which the expression(*i).mis well-defined, support the expressioni->mwith the same semantics as(*i).m. [...]
24.4.1 Iterator traits [iterator.traits]
[...] In addition, the types
iterator_traits<Iterator>::reference iterator_traits<Iterator>::pointershall be defined as the iterator’s reference and pointer types, that is, for an iterator object
a, the same type as the type of*aanda->, 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
referencetype 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_typeis a class, however, it must still be possible to access members throughoperator->. Therefore, an iterator whosereferencetype 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_facadeimplementation.
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