<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2962: Iterators of Containers of move-only types do not model InputIterator</title>
<meta property="og:title" content="Issue 2962: Iterators of Containers of move-only types do not model InputIterator">
<meta property="og:description" content="C++ library issue. Status: Open">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2962.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#Open">Open</a> status.</em></p>
<h3 id="2962"><a href="lwg-active.html#2962">2962</a>. Iterators of Containers of move-only types do not model <code>InputIterator</code></h3>
<p><b>Section:</b> 24.3.5.3 <a href="https://wg21.link/input.iterators">[input.iterators]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a>
 <b>Submitter:</b> Ga&scaron;per A&zcaron;man <b>Opened:</b> 2017-05-10 <b>Last modified:</b> 2022-04-25</p>
<p><b>Priority: </b>2
</p>
<p><b>View other</b> <a href="lwg-index-open.html#input.iterators">active issues</a> in [input.iterators].</p>
<p><b>View all other</b> <a href="lwg-index.html#input.iterators">issues</a> in [input.iterators].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Open">Open</a> status.</p>
<p><b>Discussion:</b></p>
<p>
In Table 95 in 24.3.5.3 <a href="https://wg21.link/input.iterators">[input.iterators]</a>, it is specified that the expression <code>*a</code> returns <code>reference</code>, 
which must be convertible to <code>value_type</code>. This is not true for move-only types, which incidentally means that
<code>std::vector&lt;std::unique_ptr&lt;int&gt;&gt;</code> does not possess even a lowly <code>InputIterator</code>, which is, of 
course, absurd.
<p/>
With the advent of concepts as first-class citizens in the language, getting this right as soon as possible is a priority.
<p/>
This issue seems to be similar to both LWG <a href="lwg-defects.html#448" title="Random Access Iterators over abstract classes (Status: CD1)">448</a><sup><a href="https://cplusplus.github.io/LWG/issue448" title="Latest snapshot">(i)</a></sup> and LWG <a href="lwg-active.html#484" title="Convertible to T (Status: Open)">484</a><sup><a href="https://cplusplus.github.io/LWG/issue484" title="Latest snapshot">(i)</a></sup>, but not the same.
<p/>
The proposed resolution stems from two considerations outlined below:
</p>
<blockquote>
<p>
<b>Convertibility is too strong for all algorithms</b>
<p/>
No algorithm in the standard library requires convertibility to <code>value_type</code>. If algorithms require things that smell 
of that, they specify the assignment or constructibility flavor they need directly. I checked this by going through the 
specification of each and every one of them in <code>&lt;algorithm&gt;</code> and <code>&lt;numeric&gt;</code>, which highlighted 
several issues unrelated to this one. These issues are presented in <em>Algorithms with underspecified iterator requirements</em>
(LWG <a href="lwg-active.html#2963" title="Algorithms with underspecified iterator requirements (Status: New)">2963</a><sup><a href="https://cplusplus.github.io/LWG/issue2963" title="Latest snapshot">(i)</a></sup>).
<p/>
<b><code>reference</code> needs to be related to <code>value_type</code></b>
<p/>
Algorithms need this for the following reasons:
</p>
<ul>
<li><p>lifetime-extension: served as adequately by <code>T const&amp;</code> as by <code>T</code>. Also works for iterators that 
return by value. <code>T&amp;&amp;</code> also correctly binds to <code>T const&amp;</code>.</p></li>
<li><p>passing to predicates: again, served adequately by <code>T const&amp;</code></p></li>
<li><p>writing to <code>*result</code>: not provided by the requirement anyway.</p></li>
<li><p>capture-by-copy: currently implicitly guaranteed, but unused in the standard library (always specified separately). 
A separate specification can always be made for algorithms that need to capture-by-copy.</p></li>
</ul>
<p>
We must give due consideration to code that so far required its inputs to be <code>CopyConstructible</code> implicitly by 
requiring convertibility to <code>T</code>. This is done in the issue LWG <a href="lwg-active.html#2963" title="Algorithms with underspecified iterator requirements (Status: New)">2963</a><sup><a href="https://cplusplus.github.io/LWG/issue2963" title="Latest snapshot">(i)</a></sup>, 
which presents the results of a comb-through of <code>&lt;algorithm&gt;</code> and <code>&lt;numeric&gt;</code> to find algorithms 
that have this requirement, but where it is not specified. While related issues have been identified, no algorithms seems 
to require more than <code>T const&amp;</code> convertibility without separately requiring convertibility to <code>T</code>.
<p/>
Since such code is already compiling today, relaxing this requirement does not break code.
<p/>
The only code this could possibly break is if, in a concept checking library, the <code>InputIterator</code> concept requirement 
on <code>reference</code> being convertible to <code>value_type</code> gets relaxed. Such a library, if it offered overloading based 
on most-specific modeled concept, could now, once fixed, resolve the call to a different algorithm, which could break user 
code that uses a hypothetical algorithm with a move-only container and was relying to select some other overload for move-only 
types based on the implicit <code>CopyConstructible</code> assertion provided by the iterator.
<p/>
In our internal concepts-checking library, we have had this issue "fixed" since the very beginning &mdash; move-only types 
were too important for our internal algorithms library, and also no algorithm in it seems to require something like 
<code>Iterator::value_type x = *first</code> without also requiring copy-constructibility anyway.
</p>
</blockquote>

<p><i>[2017-07 Toronto Monday issue prioritization]</i></p>

<p>Priority 2; also could affect the ranges TS</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>This wording is relative to <a href="https://wg21.link/n4659">N4659</a>.</p>

<ol>
<li>
<p>Change Table 95 &mdash; "Input iterator requirements", 24.3.5.3 <a href="https://wg21.link/input.iterators">[input.iterators]</a> as indicated:</p>

<blockquote>
<table border="1">
<caption>Table 107 &mdash; Input iterator requirements (in addition to Iterator)</caption>
<tr>
<th>Expression</th>
<th>Return type</th>
<th>Operational<br/>semantics</th>
<th>Assertion&#47;note pre-&#47;post-condition</th>
</tr>

<tr>
<td colspan="4" align="center">
<code>&hellip;</code>
</td>
</tr>

<tr>
<td>
<code>*a</code>
</td>
<td>
<code>reference</code>,<br/>
<del>convertible to <code>T</code></del><br/>
<ins>that binds to <code>const T&amp;</code></ins>
</td>
<td>
<code></code>
</td>
<td>
[&hellip;]
</td>
</tr>

<tr>
<td colspan="4" align="center">
<code>&hellip;</code>
</td>
</tr>

<tr>
<td>
<code>*r++</code>
</td>
<td>
<del>convertible to <code>T</code></del><br/>
<ins>that binds to <code>const T&amp;</code></ins>
</td>
<td>
<code>
{ <del>T</del><ins>auto&amp;&amp;</ins> tmp = *r;<br/>
++r;<br/>
return tmp; }
</code>
</td>
<td>
</td>
</tr>

</table>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2018-04-20; Eric Niebler provides improved wording]</i></p>

<p>
The revised wording makes it clear that you can only rely on those operational semantics when 
the value type is constructible from the reference type and is movable. When those conditions 
aren't met, we can make no guarantees about the operational semantics of <code>*r++</code> (which 
is why <code>*r++</code> is no longer a required expression of the <code>InputIterator</code> concept 
in the Ranges TS).
<p/>
Really, <em>no</em> generic code should be doing <code>*r++</code> on input iterators. Another 
option would be to simply deprecate this requirement for input iterators, but that might need 
a paper. (For forward iterators, <code>*r++</code> is already required to return <code>reference</code> 
exactly, and the multi-pass guarantee gives it the proper semantics.)
<p/>
I also now have a question about the proposed return type of <code>*a</code> and <code>*r++</code>, 
which says they must be something that "binds to <code>const T&amp;</code>". Does this mean that an 
iterator with a reference type reference-to-[<code>const</code>?]-<code>volatile</code>-<code>T</code> is no longer 
considered an iterator? I don't think that's what we want to say. Perhaps these should read 
"binds to <code>const volatile T&amp;</code> instead, except that has the problem for InputIterators 
that return prvalues that a prvalue is not bindable to a volatile reference.
</p>

<p><i>[2018-11 San Diego Thursday night issue processing]</i></p>

<p>Look at Ranges; EricWF to investigate. Status to Open</p>

<p>
<strong>Previous resolution [SUPERSEDED]:</strong>
</p>
<blockquote class="note">
<p>
This wording is relative to <a href="https://wg21.link/N4741" title=" Working Draft, Standard for Programming Language C++">N4741</a>.
</p>

<ol>
<li>
<p>Change Table 89 &mdash; "Input iterator requirements", 24.3.5.3 <a href="https://wg21.link/input.iterators">[input.iterators]</a> as indicated:</p>

<blockquote>
<table border="1">
<caption>Table 89 &mdash; Input iterator requirements (in addition to Iterator)</caption>
<tr>
<th>Expression</th>
<th>Return type</th>
<th>Operational<br/>semantics</th>
<th>Assertion&#47;note pre-&#47;post-condition</th>
</tr>

<tr>
<td colspan="4" align="center">
<code>&hellip;</code>
</td>
</tr>

<tr>
<td>
<code>*a</code>
</td>
<td>
<code>reference</code>,<br/>
<del>convertible to <code>T</code></del><br/>
<ins>that binds to <code>const T&amp;</code></ins>
</td>
<td>
<code></code>
</td>
<td>
[&hellip;]
</td>
</tr>

<tr>
<td colspan="4" align="center">
<code>&hellip;</code>
</td>
</tr>

<tr>
<td>
<code>*r++</code>
</td>
<td>
<del>convertible to <code>T</code></del><br/>
<ins>that binds to <code>const T&amp;</code></ins>
</td>
<td>
<ins>When <code>T tmp = *r</code> is well-formed and<br/> 
<code>T</code> is <code>MoveConstructible</code>, then<br/></ins>
<code>
{ T tmp = *r;<br/>
++r;<br/>
return tmp; }
</code>
</td>
<td>
</td>
</tr>

</table>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2022-04-25; Daniel rebases wording on <a href="https://wg21.link/N4910" title=" Working Draft, Standard for Programming Language C++">N4910</a>]</i></p>



<p id="res-2962"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4910" title=" Working Draft, Standard for Programming Language C++">N4910</a>.
</p>

<ol>
<li>
<p>Change 24.3.5.3 <a href="https://wg21.link/input.iterators">[input.iterators]</a>, Table 83 &mdash; "<i>Cpp17InputIterator</i> requirements (in addition to 
<i>Cpp17Iterator</i>) [tab:inputiterator]" as indicated:</p>

<blockquote>
<table border="1">
<caption>Table 83 &mdash; <i>Cpp17InputIterator</i> requirements (in addition to <i>Cpp17Iterator</i>) [tab:inputiterator]</caption>
<tr>
<th>Expression</th>
<th>Return type</th>
<th>Operational<br/>semantics</th>
<th>Assertion&#47;note pre-&#47;post-condition</th>
</tr>

<tr>
<td colspan="4" align="center">
<code>&hellip;</code>
</td>
</tr>

<tr>
<td>
<code>*a</code>
</td>
<td>
<code>reference</code>,<br/>
<del>convertible to <code>T</code></del><br/>
<ins>that binds to <code>const T&amp;</code></ins>
</td>
<td>
<code></code>
</td>
<td>
[&hellip;]
</td>
</tr>

<tr>
<td colspan="4" align="center">
<code>&hellip;</code>
</td>
</tr>

<tr>
<td>
<code>*r++</code>
</td>
<td>
<del>convertible to <code>T</code></del><br/>
<ins>that binds to <code>const T&amp;</code></ins>
</td>
<td>
<ins>When <code>T tmp = *r</code> is well-formed and<br/> 
<code>T</code> is <i>Cpp17MoveConstructible</i>, then<br/></ins>
<code>
{ T tmp = *r;<br/>
++r;<br/>
return tmp; }
</code>
</td>
<td>
</td>
</tr>

</table>
</blockquote>
</li>
</ol>





</body>
</html>
