<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 103: set::iterator is required to be modifiable, but this allows modification of keys</title>
<meta property="og:title" content="Issue 103: set::iterator is required to be modifiable, but this allows modification of keys">
<meta property="og:description" content="C++ library issue. Status: CD1">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue103.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="103"><a href="lwg-defects.html#103">103</a>. set::iterator is required to be modifiable, but this allows modification of keys</h3>
<p><b>Section:</b> 23.2.7 <a href="https://wg21.link/associative.reqmts">[associative.reqmts]</a> <b>Status:</b> <a href="lwg-active.html#CD1">CD1</a>
 <b>Submitter:</b> AFNOR <b>Opened:</b> 1998-10-07 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="lwg-index-open.html#associative.reqmts">active issues</a> in [associative.reqmts].</p>
<p><b>View all other</b> <a href="lwg-index.html#associative.reqmts">issues</a> in [associative.reqmts].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#CD1">CD1</a> status.</p>
<p><b>Discussion:</b></p>
<p>Set::iterator is described as implementation-defined with a
reference to the container requirement; the container requirement says
that const_iterator is an iterator pointing to const T and iterator an
iterator pointing to T.</p>

<p>23.1.2 paragraph 2 implies that the keys should not be modified to
break the ordering of elements. But that is not clearly
specified. Especially considering that the current standard requires
that iterator for associative containers be different from
const_iterator. Set, for example, has the following: </p>

<p><code>typedef implementation defined iterator;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // See _lib.container.requirements_</code></p>

<p>23.2 <a href="https://wg21.link/container.requirements">[container.requirements]</a> actually requires that iterator type pointing
to T (table 65). Disallowing user modification of keys by changing the
standard to require an iterator for associative container to be the
same as const_iterator would be overkill since that will unnecessarily
significantly restrict the usage of associative container. A class to
be used as elements of set, for example, can no longer be modified
easily without either redesigning the class (using mutable on fields
that have nothing to do with ordering), or using const_cast, which
defeats requiring iterator to be const_iterator. The proposed solution
goes in line with trusting user knows what he is doing. </p>

<p><b>Other Options Evaluated:</b> </p>

<p>Option A.&nbsp;&nbsp; In 23.2.7 <a href="https://wg21.link/associative.reqmts">[associative.reqmts]</a>, paragraph 2, after
first sentence, and before &quot;In addition,...&quot;, add one line:
</p>

<blockquote>
  <p>Modification of keys shall not change their strict weak ordering. </p>
</blockquote>

<p>Option B.&nbsp;Add three new sentences to 23.2.7 <a href="https://wg21.link/associative.reqmts">[associative.reqmts]</a>:</p>

<blockquote>
  <p>At the end of paragraph 5: &quot;Keys in an associative container
  are immutable.&quot; At the end of paragraph 6: &quot;For
  associative containers where the value type is the same as the key
  type, both <code>iterator</code> and <code>const_iterator</code> are
  constant iterators. It is unspecified whether or not
  <code>iterator</code> and <code>const_iterator</code> are the same
  type.&quot;</p>
</blockquote>

<p>Option C.&nbsp;To 23.2.7 <a href="https://wg21.link/associative.reqmts">[associative.reqmts]</a>, paragraph 3, which
currently reads:</p>

<blockquote>
  <p>The phrase ``equivalence of keys'' means the equivalence relation imposed by the
  comparison and not the operator== on keys. That is, two keys k1 and k2 in the same
  container are considered to be equivalent if for the comparison object comp, comp(k1, k2)
  == false &amp;&amp; comp(k2, k1) == false.</p>
</blockquote>

<p>&nbsp; add the following:</p>

<blockquote>
  <p>For any two keys k1 and k2 in the same container, comp(k1, k2) shall return the same
  value whenever it is evaluated. [Note: If k2 is removed from the container and later
  reinserted, comp(k1, k2) must still return a consistent value but this value may be
  different than it was the first time k1 and k2 were in the same container. This is
  intended to allow usage like a string key that contains a filename, where comp compares
  file contents; if k2 is removed, the file is changed, and the same k2 (filename) is
  reinserted, comp(k1, k2) must again return a consistent value but this value may be
  different than it was the previous time k2 was in the container.]</p>
</blockquote>



<p id="res-103"><b>Proposed resolution:</b></p>
<p>Add the following to 23.2.7 <a href="https://wg21.link/associative.reqmts">[associative.reqmts]</a> at
the indicated location:</p>

<blockquote>
  <p>At the end of paragraph 3: &quot;For any two keys k1 and k2 in the same container,
  calling comp(k1, k2) shall always return the same
  value.&quot;</p>
  <p>At the end of paragraph 5: &quot;Keys in an associative container are immutable.&quot;</p>
  <p>At the end of paragraph 6: &quot;For associative containers where the value type is the
  same as the key type, both <code>iterator</code> and <code>const_iterator</code> are constant
  iterators. It is unspecified whether or not <code>iterator</code> and <code>const_iterator</code>
  are the same type.&quot;</p>
</blockquote>


<p><b>Rationale:</b></p>
<p>Several arguments were advanced for and against allowing set elements to be
mutable as long as the ordering was not effected. The argument which swayed the
LWG was one of safety; if elements were mutable, there would be no compile-time
way to detect of a simple user oversight which caused ordering to be
modified.  There was a report that this had actually happened in practice,
and had been painful to diagnose.  If users need to modify elements,
it is possible to use mutable members or const_cast.</p>

<p>Simply requiring that keys be immutable is not sufficient, because the comparison
object may indirectly (via pointers) operate on values outside of the keys.</p>

<p>
The types <code>iterator</code> and <code>const_iterator</code> are permitted
to be different types to allow for potential future work in which some
member functions might be overloaded between the two types.  No such
member functions exist now, and the LWG believes that user functionality
will not be impaired by permitting the two types to be the same.  A
function that operates on both iterator types can be defined for 
<code>const_iterator</code> alone, and can rely on the automatic
conversion from <code>iterator</code> to <code>const_iterator</code>.
</p>

<p><i>[Tokyo: The LWG crafted the proposed resolution and rationale.]</i></p>






</body>
</html>
