<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 445: iterator_traits::reference unspecified for some iterator categories</title>
<meta property="og:title" content="Issue 445: iterator_traits::reference unspecified for some iterator categories">
<meta property="og:description" content="C++ library issue. Status: CD1">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue445.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#CD1">CD1</a> status.</em></p>
<h3 id="445"><a href="lwg-defects.html#445">445</a>. iterator_traits::reference unspecified for some iterator categories</h3>
<p><b>Section:</b> 24.3.2.3 <a href="https://wg21.link/iterator.traits">[iterator.traits]</a> <b>Status:</b> <a href="lwg-active.html#CD1">CD1</a>
 <b>Submitter:</b> Dave Abrahams <b>Opened:</b> 2003-12-09 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#iterator.traits">issues</a> in [iterator.traits].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#CD1">CD1</a> status.</p>
<p><b>Discussion:</b></p>
<p>
The standard places no restrictions at all on the reference type
of input, output, or forward iterators (for forward iterators it
only specifies that *x must be value_type&amp; and doesn't mention
the reference type).  Bidirectional iterators' reference type is
restricted only by implication, since the base iterator's
reference type is used as the return type of reverse_iterator's
operator*, which must be T&amp; in order to be a conforming forward
iterator.
</p>

<p>
Here's what I think we ought to be able to expect from an input
or forward iterator's reference type R, where a is an iterator
and V is its value_type
</p>

<ul>
  <li>
      *a is convertible to R
  </li>

  <li>
      R is convertible to V
  </li>

  <li>
      static_cast&lt;V&gt;(static_cast&lt;R&gt;(*a)) is equivalent to
      static_cast&lt;V&gt;(*a) 
  </li>
</ul>

<p>A mutable forward iterator ought to satisfy, for x of type V:</p>
  <pre>
      { R r = *a; r = x; } is equivalent to *a = x;
  </pre>

<p>
I think these requirements capture existing container iterators
(including vector&lt;bool&gt;'s), but render istream_iterator invalid;
its reference type would have to be changed to a constant
reference.
</p>


<p>
(Jeremy Siek) During the discussion in Sydney, it was felt that a
simpler long term solution for this was needed. The solution proposed
was to require <code>reference</code> to be the same type as <code>*a</code>
and <code>pointer</code> to be the same type as <code>a-&gt;</code>.  Most
iterators in the Standard Library already meet this requirement. Some
iterators are output iterators, and do not need to meet the
requirement, and others are only specified through the general
iterator requirements (which will change with this resolution). The
sole case where there is an explicit definition of the reference type
that will need to change is <code>istreambuf_iterator</code> which returns
<code>charT</code> from <code>operator*</code> but has a reference type of
<code>charT&amp;</code>. We propose changing the reference type of
<code>istreambuf_iterator</code> to <code>charT</code>.
</p>

<p>The other option for resolving the issue with <code>pointer</code>,
  mentioned in the note below, is to remove <code>pointer</code>
  altogether. I prefer placing requirements on <code>pointer</code> to
  removing it for two reasons. First, <code>pointer</code> will become
  useful for implementing iterator adaptors and in particular,
  <code>reverse_iterator</code> will become more well defined. Second,
  removing <code>pointer</code> is a rather drastic and publicly-visible
  action to take.</p>

<p>The proposed resolution technically enlarges the requirements for
iterators, which means there are existing iterators (such as
<code>istreambuf_iterator</code>, and potentially some programmer-defined
iterators) that will no longer meet the requirements. Will this break
existing code? The scenario in which it would is if an algorithm
implementation (say in the Standard Library) is changed to rely on
<code>iterator_traits::reference</code>, and then is used with one of the
iterators that do not have an appropriately defined
<code>iterator_traits::reference</code>.
</p>


<p>The proposed resolution makes one other subtle change. Previously,
it was required that output iterators have a <code>difference_type</code>
and <code>value_type</code> of <code>void</code>, which means that a forward
iterator could not be an output iterator. This is clearly a mistake,
so I've changed the wording to say that those types may be
<code>void</code>.
</p>



<p id="res-445"><b>Proposed resolution:</b></p>

<p>In 24.3.2.3 <a href="https://wg21.link/iterator.traits">[iterator.traits]</a>, after:</p>

<blockquote><p>
be defined as the iterator's difference type, value type and iterator
category, respectively.
</p></blockquote>

<p>add</p>

<blockquote><p>
In addition, the types</p>
<pre>
iterator_traits&lt;Iterator&gt;::reference
iterator_traits&lt;Iterator&gt;::pointer
</pre>
<p>must be defined as the iterator's reference and pointer types, that
is, the same type as the type of <code>*a</code> and <code>a-&gt;</code>,
respectively.</p>
</blockquote>

<p>In 24.3.2.3 <a href="https://wg21.link/iterator.traits">[iterator.traits]</a>, change:</p>

<blockquote><p>
In the case of an output iterator, the types</p>
<pre>
iterator_traits&lt;Iterator&gt;::difference_type
iterator_traits&lt;Iterator&gt;::value_type
</pre>
<p>are both defined as <code>void</code>.</p>
</blockquote>

<p>to:</p>
<blockquote><p>
In the case of an output iterator, the types</p>
<pre>
iterator_traits&lt;Iterator&gt;::difference_type
iterator_traits&lt;Iterator&gt;::value_type
iterator_traits&lt;Iterator&gt;::reference
iterator_traits&lt;Iterator&gt;::pointer
</pre>
<p>may be defined as <code>void</code>.</p>
</blockquote>

<p>In 24.6.4 <a href="https://wg21.link/istreambuf.iterator">[istreambuf.iterator]</a>, change:</p>
<blockquote>
<pre>
typename traits::off_type, charT*, charT&amp;&gt;
</pre>
</blockquote>
<p>to:</p>
<blockquote>
<pre>
typename traits::off_type, charT*, charT&gt;
</pre>
</blockquote>

<p><i>[
Redmond: there was concern in Sydney that this might not be the only place
where things were underspecified and needed to be changed.  Jeremy
reviewed iterators in the standard and confirmed that nothing else
needed to be changed.
]</i></p>









</body>
</html>
