This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++17 status.

### 2437. `iterator_traits<OutIt>::reference` can and can't be `void`

Section: 23.3.5.2 [iterator.iterators] Status: C++17 Submitter: Stephan T. Lavavej Opened: 2014-10-01 Last modified: 2017-07-30

Priority: 3

View all other issues in [iterator.iterators].

View all issues with C++17 status.

Discussion:

23.3.5.2 [iterator.iterators]/2 requires an `Iterator`'s `*r` to return `reference`, i.e. `iterator_traits<X>::reference` according to 23.3.1 [iterator.requirements.general]/11.

23.3.5.4 [output.iterators]/1 requires an `OutputIterator`'s `*r = o` to do its job, so `*r` clearly can't return `void`.

23.3.2.3 [iterator.traits]/1 says: "In the case of an output iterator, the types

>     iterator_traits<Iterator>::difference_type
>     iterator_traits<Iterator>::value_type
>     iterator_traits<Iterator>::reference
>     iterator_traits<Iterator>::pointer

may be defined as `void`."

This is contradictory. I suggest fixing this by moving the offending requirement down from `Iterator` to `InputIterator`, and making `Iterator` say that `*r` returns an unspecified type. This will have the following effects:

- Output-only iterators will inherit Iterator's "`*r` returns unspecified" requirement, while 23.3.2.3 [iterator.traits]/1 clearly permits reference/etc. to be `void`.

- Input-or-stronger iterators (whether constant or mutable) are unaffected — they still have to satisfy "`*r` returns reference", they're just getting that requirement from `InputIterator` instead of `Iterator`.

[2015-02 Cologne]

EF: This is related to 2438. MC: I'd like to take up 2438 right after this.

AM: Does anyone think this is wrong?

GR: Why do we give output iterators to have reference type void? AM: we've mandated that certain output iterators define it as void since 1998. GR: Oh OK, I'm satisfied.

Accepted. And 2438 is already Ready.

Proposed resolution:

This wording is relative to N3936.

1. In 23.3.5.2 [iterator.iterators] Table 106 "Iterator requirements" change as indicated:

   > Table 106 — Iterator requirements
   > Expression | Return type | Operational semantics | Assertion/note pre-/post-condition
   > --- | --- | --- | ---
   > `*r` | `reference` unspecified | `` | pre: `r` is dereferenceable.
   > `…`

2. In 23.3.5.3 [input.iterators] Table 107 "Input iterator requirements" change as indicated:

   > Table 107 — Input iterator requirements (in addition to Iterator)
   > Expression | Return type | Operational semantics | Assertion/note pre-/post-condition
   > --- | --- | --- | ---
   > `…`
   > `*a` | `reference`, convertible to `T` | `` | […]
   > `…`