<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2263: Comparing iterators and allocator pointers with different const-character</title>
<meta property="og:title" content="Issue 2263: Comparing iterators and allocator pointers with different const-character">
<meta property="og:description" content="C++ library issue. Status: C++14">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2263.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#C++14">C++14</a> status.</em></p>
<h3 id="2263"><a href="lwg-defects.html#2263">2263</a>. Comparing iterators and allocator pointers with different const-character</h3>
<p><b>Section:</b> 16.4.4.6 <a href="https://wg21.link/allocator.requirements">[allocator.requirements]</a>, 23.2 <a href="https://wg21.link/container.requirements">[container.requirements]</a> <b>Status:</b> <a href="lwg-active.html#C++14">C++14</a>
 <b>Submitter:</b> Howard Hinnant <b>Opened:</b> 2013-06-25 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>1
</p>
<p><b>View other</b> <a href="lwg-index-open.html#allocator.requirements">active issues</a> in [allocator.requirements].</p>
<p><b>View all other</b> <a href="lwg-index.html#allocator.requirements">issues</a> in [allocator.requirements].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++14">C++14</a> status.</p>
<p><b>Discussion:</b></p>
<p>
This ancient issue <a href="lwg-defects.html#179" title="Comparison of const_iterators to iterators doesn't work (Status: CD1)">179</a><sup><a href="https://cplusplus.github.io/LWG/issue179" title="Latest snapshot">(i)</a></sup> says one ought to be able to compare iterators with <code>const_iterators</code> 
from any given container.  I'm having trouble finding words that guarantee this in C++11.  This impacts not only a 
container's iterators, but also the allocator requirements in  [llocator.requirements] surrounding 
<code>pointer</code>, <code>const_pointer</code>, <code>void_pointer</code> and <code>const_void_pointer</code>.  E.g. can one 
compare a <code>pointer</code> with a <code>const_pointer</code>? 
<p/>
Since <code>allocator::pointer</code> and <code>const_pointer</code> are required to be random access iterators, one could 
expect that the <a href="lwg-defects.html#179" title="Comparison of const_iterators to iterators doesn't work (Status: CD1)">179</a><sup><a href="https://cplusplus.github.io/LWG/issue179" title="Latest snapshot">(i)</a></sup> guarantees apply for them as well.
</p>

<p><i>[
Daniel comments:
]</i></p>


<p>
The wording for <a href="lwg-defects.html#179" title="Comparison of const_iterators to iterators doesn't work (Status: CD1)">179</a><sup><a href="https://cplusplus.github.io/LWG/issue179" title="Latest snapshot">(i)</a></sup> was part of several working drafts (e.g. also in 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3092.pdf">N3092</a>) over some time and suddenly got lost
in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf">N3242</a>, presumably by accident. Whatever we
decide for allocator pointers, I expect that we need to restore the  <a href="lwg-defects.html#179" title="Comparison of const_iterators to iterators doesn't work (Status: CD1)">179</a><sup><a href="https://cplusplus.github.io/LWG/issue179" title="Latest snapshot">(i)</a></sup> wording as part of the overall resolution:
</p>

<p>Reinsert after 23.2 <a href="https://wg21.link/container.requirements">[container.requirements]</a> p6:</p>

<blockquote>
<p>
-6- <code>begin()</code> returns an iterator referring to the first element in the container. <code>end()</code> returns an iterator which
is the past-the-end value for the container. If the container is empty, then <code>begin() == end()</code>;
<p/>
<ins>-?- In the expressions</ins>
</p>
<blockquote><pre>
<ins>i == j
i != j
i &lt; j
i &lt;= j
i &gt;= j
i &gt; j
i - j</ins>
</pre></blockquote>
<p>
<ins>where <code>i</code> and <code>j</code> denote objects of a container's <code>iterator</code> type, either or both may be replaced by an object 
of the container's <code>const_iterator</code> type referring to the same element with no change in semantics.</ins>
</p>
</blockquote>

<p><i>[2014-02-13 Issaquah, Daniel comments and suggests wording]</i></p>


<p>
First, I didn't originally move the seemingly lost wording to the resolution section because I wanted to ensure that the 
committee double-checks the reason of this loss. 
<p/>
Second, albeit restoring this wording will restore the comparability of <code>const_iterator</code> and <code>iterator</code> of
containers specified in Clause 23, but this alone would <em>not</em> imply that this guarantee automatically extends to
<em>all other</em> iterators, simply because there is no fundamental relation between a mutable iterator and a constant
iterator by itself. This relation only exists under specific conditions, for example for containers which provide two such
<code>typedefs</code> of that kind. Thus the wording restoration would <em>not</em> ensure that allocator <code>pointer</code> and 
<code>const_pointer</code> would be comparable with each other. To realize that, we would need additional guarantees added
to the allocator requirements. In fact, it is crucial to separate these things, because allocators are <em>not</em> 
restricted to be used within containers, they have their own legitimate use for other places as well (albeit containers
presumably belong to the most important use-cases), and this is also stated in the introduction of 16.4.4.6 <a href="https://wg21.link/allocator.requirements">[allocator.requirements]</a>,
where it says:
</p>
<blockquote><p>
All of the string types (Clause 21), containers (Clause 23) (except array), string buffers and string streams (Clause 27), 
and <code>match_results</code> (Clause 28) are parameterized in terms of allocators.
</p></blockquote>

<p><i>[2014-02-12 Issaquah meeting]</i></p>

<p>
Move a Immediate.
</p>



<p id="res-2263"><b>Proposed resolution:</b></p>
<ol>
<li><p>Insert after 16.4.4.6 <a href="https://wg21.link/allocator.requirements">[allocator.requirements]</a> p4 as indicated:</p>

<blockquote><p>
-4- An allocator type <code>X</code> shall satisfy the requirements of <code>CopyConstructible</code> (17.6.3.1). The <code>X::pointer</code>,
<code>X::const_pointer</code>, <code>X::void_pointer</code>, and <code>X::const_void_pointer</code> types shall satisfy the requirements
of <code>NullablePointer</code> (17.6.3.3). No constructor, comparison operator, copy operation, move operation, or
swap operation on these types shall exit via an exception. <code>X::pointer</code> and <code>X::const_pointer</code> shall also
satisfy the requirements for a random access iterator (24.2).
<p/>
<ins>-?- Let <code>x1</code> and <code>x2</code> denote objects of (possibly different) types <code>X::void_pointer</code>, 
<code>X::const_void_pointer</code>, <code>X::pointer</code>, or <code>X::const_pointer</code>. Then, <code>x1</code> and <code>x2</code>
are <em>equivalently-valued</em> pointer values, if and only if both <code>x1</code> and <code>x2</code> can be explicitly converted 
to the two corresponding objects <code>px1</code> and <code>px2</code> of type <code>X::const_pointer</code>, using a sequence of
<code>static_cast</code>s using only these four types, and the expression <code>px1 == px2</code> evaluates to <code>true</code>.</ins>
</p>
<blockquote class="note"><p>
<em>Drafting note:</em> This wording uses the seemingly complicated route via <code>X::const_pointer</code>, because these are (contrary to
<code>X::const_void_pointer</code>) random access iterators and we can rely here for dereferenceable values on the fundamental pointee
equivalence of 24.3.5.5 <a href="https://wg21.link/forward.iterators">[forward.iterators]</a> p6:
</p>
<blockquote><p>
If <code>a</code> and <code>b</code> are both dereferenceable, then <code>a == b</code> if and only if <code>*a</code> and <code>*b</code> are 
bound to the same object.
</p></blockquote>
<p>
while for null pointer values we can rely on the special equality relation induced by 16.4.4.4 <a href="https://wg21.link/nullablepointer.requirements">[nullablepointer.requirements]</a>.
</p>
</blockquote>
<p>
<ins>-?- Let <code>w1</code> and <code>w2</code> denote objects of type <code>X::void_pointer</code>. Then for the expressions</ins>
</p>
<blockquote><pre>
<ins>w1 == w2
w1 != w2</ins>
</pre></blockquote>
<p>
<ins>either or both objects may be replaced by an equivalently-valued object of type <code>X::const_void_pointer</code> with no 
change in semantics.</ins>
<p/>
<ins>-?- Let <code>p1</code> and <code>p2</code> denote objects of type <code>X::pointer</code>. Then for the expressions</ins>
</p>
<blockquote><pre>
<ins>p1 == p2
p1 != p2
p1 &lt; p2
p1 &lt;= p2
p1 &gt;= p2
p1 &gt; p2
p1 - p2</ins>
</pre></blockquote>
<p>
<ins>either or both objects may be replaced by an equivalently-valued object of type <code>X::const_pointer</code> with no 
change in semantics.</ins>
</p>
</blockquote>
</li>
<li><p>Reinsert after 23.2 <a href="https://wg21.link/container.requirements">[container.requirements]</a> p6:</p>

<blockquote><p>
-6- <code>begin()</code> returns an iterator referring to the first element in the container. <code>end()</code> returns an iterator which
is the past-the-end value for the container. If the container is empty, then <code>begin() == end()</code>;
<p/>
<ins>-?- In the expressions</ins>
</p>
<blockquote><pre>
<ins>i == j
i != j
i &lt; j
i &lt;= j
i &gt;= j
i &gt; j
i - j</ins>
</pre></blockquote>
<p>
<ins>where <code>i</code> and <code>j</code> denote objects of a container's <code>iterator</code> type, either or both may be replaced by an object 
of the container's <code>const_iterator</code> type referring to the same element with no change in semantics.</ins>
</p>
</blockquote>
</li>
</ol>





</body>
</html>
