5

I use ostreambuf_iterator as the case below:

Before c++17,

template< class CharT, class Traits = std::char_traits<CharT> >
class ostreambuf_iterator : public std::iterator<std::output_iterator_tag,
                                                 void, void, void, void>

requires us to determinate every parameter type of std::iterator, so, for std::ostreambuf_iterator, void is not so bad.

As we know, std::iterator deprecated in c++17. So, iterators, should typedef their member types inside their own body, for example:

Member type           Definition
---------------------------------------------
value_type                  void
difference_type          void
pointer                        void
reference                     void
iterator_category       std::output_iterator_tag

Question:

Why should these void types still be typedefed? IOW, I think

Member type           Definition
---------------------------------------------
iterator_category       std::output_iterator_tag

is enough. After all, the motivations for deprecating std::iterator is just to simplify the standard(library). So there should be some reasons that I cannot figure out.

After googling, I found a question about on stack overflow, and the answer said:

Defining it as a void, on the other hand, can prevent errors like:

typename Iter::value_type v = *it; //useless with an output iterator if it compiled

But I think if we don't typedef value_type, such errors can also be prevented.

Community
  • 1
  • 1
Chen Li
  • 4,824
  • 3
  • 28
  • 55
  • I would say it is related to [std::iterator_traits](https://en.cppreference.com/w/cpp/iterator/iterator_traits) (which is SFINAE friendly since C++17) – Jarod42 Nov 07 '18 at 10:40
  • `T*` is a [*ContiguousIterator*](https://en.cppreference.com/w/cpp/named_req/ContiguousIterator), but does not have a member `value_type`. You should use `typename std::iterator_traits::value_type` not `typename Iter::value_type` when you want to handle **all iterators** – Caleth Nov 07 '18 at 11:03

1 Answers1

5

Because ISO C++17 std::iteartor_traits needs all the 5 of these member types in general, even if it is already SFINAE-friendly since C++17. If there are insufficient nested types, the instance of std::iterator_traits will have no members desired. Currently, this is not changed in the current draft.

See also iterator_traits SFINAE friendliness for rationale of the original proposal.

FrankHB
  • 2,297
  • 23
  • 19