std::iterator
inheritance shouldn't be mandatedSection: D.17 [depr.iterator] Status: C++17 Submitter: Stephan T. Lavavej Opened: 2014-10-01 Last modified: 2023-02-07
Priority: 3
View all issues with C++17 status.
Discussion:
For LWG convenience, nine STL iterators are depicted as deriving from std::iterator
to get their
iterator_category
/etc. typedefs. Unfortunately (and unintentionally), this also mandates the
inheritance, which is observable (not just through is_base_of
, but also overload resolution).
This is unfortunate because it confuses users, who can be misled into thinking that their own iterators
must derive from std::iterator
, or that overloading functions to take std::iterator
is
somehow meaningful. This is also unintentional because the STL's most important iterators, the container
iterators, aren't required to derive from std::iterator
. (Some are even allowed to be raw pointers.)
Finally, this unnecessarily constrains implementers, who may not want to derive from std::iterator
.
(For example, to simplify debugger views.)
std::iterator
if they want.
(Editorial note: The order of the typedefs follows the order of std::iterator
's template parameters.)
[Urbana 2014-11-07: Move to Ready]
Proposed resolution:
This wording is relative to N3936.
Change [storage.iterator], class template raw_storage_iterator
synopsis, as depicted:
template <class OutputIterator, class T> class raw_storage_iterator: public iterator<output_iterator_tag,void,void,void,void>{ public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; explicit raw_storage_iterator(OutputIterator x); […] };
Change 24.5.1.2 [reverse.iterator], class template reverse_iterator
synopsis, as depicted
(editorial note: this reorders "reference
, pointer
" to "pointer
, reference
"
and aligns whitespace):
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;typedef Iterator iterator_type; typedef typename iterator_traits<Iterator>::iterator_category iterator_category; typedef typename iterator_traits<Iterator>::value_type value_type; typedef typename iterator_traits<Iterator>::difference_type difference_type; typedef typename iterator_traits<Iterator>::pointer pointer; typedef typename iterator_traits<Iterator>::reference reference; reverse_iterator(); […] };
Change 24.5.2.2 [back.insert.iterator], class template back_insert_iterator
synopsis, as depicted:
template <class Container> class back_insert_iterator: public iterator<output_iterator_tag,void,void,void,void>{ protected: Container* container; public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; typedef Container container_type; explicit back_insert_iterator(Container& x); […] };
Change 24.5.2.3 [front.insert.iterator], class template front_insert_iterator
synopsis, as depicted:
template <class Container> class front_insert_iterator: public iterator<output_iterator_tag,void,void,void,void>{ protected: Container* container; public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; typedef Container container_type; explicit front_insert_iterator(Container& x); […] };
Change 24.5.2.4 [insert.iterator], class template insert_iterator
synopsis, as depicted:
template <class Container> class insert_iterator: public iterator<output_iterator_tag,void,void,void,void>{ protected: Container* container; typename Container::iterator iter; public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; typedef Container container_type; insert_iterator(Container& x, typename Container::iterator i); […] };
Change 24.6.2 [istream.iterator], class template istream_iterator
synopsis, as depicted:
template <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptrdiff_t> class istream_iterator: public iterator<input_iterator_tag, T, Distance, const T*, const T&>{ public: typedef input_iterator_tag iterator_category; typedef T value_type; typedef Distance difference_type; typedef const T* pointer; typedef const T& reference; […] };
Change 24.6.3 [ostream.iterator], class template ostream_iterator
synopsis, as depicted:
template <class T, class charT = char, class traits = char_traits<charT>> class ostream_iterator: public iterator<output_iterator_tag, void, void, void, void>{ public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; […] };
Change 24.6.4 [istreambuf.iterator], class template istreambuf_iterator
synopsis, as depicted:
template <class charT = char, class traits = char_traits<charT> > class istreambuf_iterator: public iterator<input_iterator_tag, charT, typename traits::off_type, unspecified, charT>{ public: typedef input_iterator_tag iterator_category; typedef charT value_type; typedef typename traits::off_type difference_type; typedef unspecified pointer; typedef charT reference; […] };
Change 24.6.5 [ostreambuf.iterator], class template ostreambuf_iterator
synopsis, as depicted
(editorial note: this removes a redundant "public:"):
template <class charT = char, class traits = char_traits<charT>> class ostreambuf_iterator: public iterator<output_iterator_tag, void, void, void, void>{ public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; […]public:[…] };