It appears that the iterator adaptor reverse_iterator
doubly defines most of its nested types. In particular, it inherits publicly from std::iterator
which exposes iterator_category
, value_type
, difference_type
, pointer
and reference
. Except for iterator_category
and value_type
, these are all explicitly typedef
'ed again in the class definition.
24.5.1.1 Class template reverse_iterator [reverse.iterator]
namespace std {
template <class Iterator>
class reverse_iterator : public
iterator<typename iterator_traits<Iterator>::iterator_category,
typename iterator_traits<Iterator>::value_type,
typename iterator_traits<Iterator>::difference_type,
typename iterator_traits<Iterator>::pointer,
typename iterator_traits<Iterator>::reference> {
public:
typedef Iterator iterator_type;
typedef typename iterator_traits<Iterator>::difference_type difference_type;
typedef typename iterator_traits<Iterator>::reference reference;
typedef typename iterator_traits<Iterator>::pointer pointer;
// ... rest of the class
};
Question: why the repetitive definition? Is this just for purposes of exposition, or is there more to it? And why not redefine iterator_category
and value_type
?
This is more of a guess, but all those redundant
typedefs
declare types that are used within specification of the class body ofreverse_iterator
. For example (C++03 IS):Since
iterator<..>
is a dependent base class, it won't be searched for the namespointer
andreference
. Sotypedef
ing those names makes the remaining spec simpler:On the other hand,
value_type
does not appear within the class body, therefore it doesn't need a redundanttypedef
.For a while now, they've been moving away from using
std::iterator
as a base class, and toward just specifying that each iterator must define the correct type names.When they specify the base class in the standard, that constrains implementations to implement the class that way, even though the only real intent was to specify that the iterator needs to define some names. In particular, you could
is_base_of
to determine whetherstd::iterator
is a base class ofstd::reverse_iterator
. No, there's nothing polymorphic, so it's pretty silly and pointless to do so, but if you do so, the current standard says it must return true.It looks (to me) like this is more or less an accidental halfway-point in the process of moving from (more or less accidentally) requiring the use of
std::iterator
as a base class, and simply specifying the names that must be defined instd::reverse_iterator
(and various other iterators as well, of course).For those who care, the history of this includes:
N3931
Issue 2438
There's also so related discussion papers about deprecating unary_function and binary_function:
N3145
N3198
These were provided for roughly the same reasons as
std::iterator
(i.e., just to provide some typedefs in a derived class) so the reasoning behind removing them is fairly pertinent to ceasing to usestd::iterator
as a base class.