<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 1051: Specify subscript operation return types of reverse_iterator and move_iterator</title>
<meta property="og:title" content="Issue 1051: Specify subscript operation return types of reverse_iterator and move_iterator">
<meta property="og:description" content="C++ library issue. Status: NAD">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue1051.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#NAD">NAD</a> status.</em></p>
<h3 id="1051"><a href="lwg-closed.html#1051">1051</a>. Specify subscript operation return types of <code>reverse_iterator</code> and <code>move_iterator</code></h3>
<p><b>Section:</b> 24.5.1.6 <a href="https://wg21.link/reverse.iter.elem">[reverse.iter.elem]</a>, 24.5.4.6 <a href="https://wg21.link/move.iter.elem">[move.iter.elem]</a> <b>Status:</b> <a href="lwg-active.html#NAD">NAD</a>
 <b>Submitter:</b> Alisdair Meredith <b>Opened:</b> 2009-03-12 <b>Last modified:</b> 2021-06-06</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#reverse.iter.elem">issues</a> in [reverse.iter.elem].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#NAD">NAD</a> status.</p>
<p><b>Discussion:</b></p>

<p><b>Addresses UK 279 [CD1]</b></p>

<p>
The reason the return type became unspecified is LWG issue <a href="lwg-defects.html#386" title="Reverse iterator's operator[] has impossible return type (Status: CD1)">386</a><sup><a href="https://cplusplus.github.io/LWG/issue386" title="Latest snapshot">(i)</a></sup>. This
reasoning no longer applies as there are at least two ways to get the right
return type with the new language facilities added since the previous
standard.
</p>

<p>
Proposal: Specify the return type using either decltype or the Iter concept_map.
</p>

<p><i>[
Summit:
]</i></p>


<blockquote>
<p>
Under discussion. This is a general question about all iterator
adapters.
</p>
</blockquote>

<p><i>[
Howard adds post Summit:
]</i></p>


<blockquote><p>
I am requesting test cases to demonstrate a position.
</p></blockquote>

<p><i>[
2009-07-24 Daniel adds:
]</i></p>


<blockquote>
<p>
I recommend NAD. Without concepts we can no longer
restrict this member in a trivial way. Using <code>decltype</code> the
declaration would be along the lines of
</p>
<blockquote><pre>
static const Iter&amp; __base(); // not defined
auto operator[](difference_type n) const -&gt; decltype(__base()[-n-1]);
</pre></blockquote>

<p>
but once <code>reverse_iterator</code> is instantiated for some given type
<code>Iter</code> which cannot form a well-formed expression <code>__base()[-n-1]</code>
this would cause an ill-formed function declaration, diagnostic
required, and no silent SFINAE elimination.
</p>

</blockquote>

<p><i>[
2009-10 Santa Cruz:
]</i></p>


<blockquote><p>
Moved to NAD.
</p></blockquote>

<p><i>[
2009-10-22 Daniel adds:
]</i></p>


<blockquote>
<p>
IMO, my original comment regarding ill-formedness of the described
construction is still correct, but I must add that I should weaken my
assertion "Without concepts we can no longer restrict this member in
a trivial way".
</p>

<p>
In fact with the existence of default template arguments for function
templates it is not too hard to implement this like as follows, which
shows that we can indeed simulate to some sense constrained
member functions in C++0x.
</p>

<p>
My example does not really proof that the specification is easy, but
it should be possible. I assume that the implementation would not
be ABI compatible, though.
</p>

<p>
It is now your own decision how to proceed ;-)
</p>

<blockquote><pre>
#include &lt;type_traits&gt;
#include &lt;cstddef&gt;

template&lt;class T&gt;
typename std::add_rvalue_reference&lt;T&gt;::type declval();

template&lt;class It&gt;
struct reverse_iterator {
    It base;

    typedef std::ptrdiff_t difference_type;

    template&lt;class U = It, class Res =
     decltype(declval&lt;const U&amp;&gt;()[declval&lt;difference_type&gt;()])
    &gt;
    Res operator[](difference_type n) const  {
        return base[-n-1];
    }
};

struct MyIter {
};

int main() {
    reverse_iterator&lt;int*&gt; ri;
    ri[0] = 2;
    reverse_iterator&lt;MyIter&gt; ri2;
}
</pre></blockquote>

<p>
The above declaration could be simplified, but the ideal solution
</p>

<blockquote><pre>
template&lt;class U = It&gt;
  decltype(declval&lt;const U&amp;&gt;()[declval&lt;difference_type&gt;()])
     operator[](difference_type n) const;
</pre></blockquote>

<p>
does not work yet on gcc 4.4.1.
</p>

</blockquote>




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





</body>
</html>
