Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apparent inconsistency in iterator requirements

I am implementing some type-traits/concept classes to check that a type passed to a generic function satisfies the compile-time requirements for iterator types (as defined in the standard, starting from 24.2.2).

The problem is that a basic iterator requirement (Table 106) is that the type of *r (where r is a reference to an iterator of type T) is std::iterator_traits<T>::reference. However, if we consider an output iterator such as std::ostream_iterator,

http://en.cppreference.com/w/cpp/iterator/ostream_iterator

we can see how in this case the reference type is void, whereas the operator*() of the iterator type returns std::ostream_iterator &.

Clearly, I am misunderstanding something here, but I can't see what? Does it have anything to do with the fact that output iterators can be dereferenced only on the left side of an assignment?

EDIT: I would like to clarify that my question is about the inconsistency between the reference type and the type resulting from calling operator*() on std::ostream_iterator (and a bunch of other output iterators in the standard library).

like image 265
bluescarni Avatar asked Nov 01 '22 00:11

bluescarni


1 Answers

24.2.1 [iterator.requirements.general]/11

In the following sections, a and b denote values of type X or const X, difference_type and reference refer to the types iterator_traits::difference_type and iterator_traits::reference, respectively

reference is not allocator_traits<T>::reference, but iterator_traits<T>::reference.

Now, in the standard std::ostream_iterator<T> is defined as:

class ostream_iterator:
                   public iterator<output_iterator_tag, void, void, void, void> {

The last argument to the std::iterator template is the reference type, which means that iterator_traits<T>::reference is required to be void for std::ostream_iterator<T>.

At the same time, 24.2.1/1 requires:

[...] All output iterators support the expression *i = o where o is a value of some type that is in the set of types that are writable to the particular iterator type of i. [...]

This might be the part that you are missing that guarantees that the assignment works. I imagine that the reference being void somehow represents that you cannot read out of this, but I guess it could be improved.

like image 94
David Rodríguez - dribeas Avatar answered Nov 05 '22 18:11

David Rodríguez - dribeas