<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 276: Assignable requirement for container value type overly strict</title>
<meta property="og:title" content="Issue 276: Assignable requirement for container value type overly strict">
<meta property="og:description" content="C++ library issue. Status: CD1">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue276.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="276"><a href="lwg-defects.html#276">276</a>. Assignable requirement for container value type overly strict</h3>
<p><b>Section:</b> 23.2 <a href="https://wg21.link/container.requirements">[container.requirements]</a> <b>Status:</b> <a href="lwg-active.html#CD1">CD1</a>
 <b>Submitter:</b> Peter Dimov <b>Opened:</b> 2000-11-07 <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#container.requirements">issues</a> in [container.requirements].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#CD1">CD1</a> status.</p>
<p><b>Discussion:</b></p>
<p>
23.1/3 states that the objects stored in a container must be
Assignable.  23.4.3 <a href="https://wg21.link/map">[map]</a>, paragraph 2,
states that map satisfies all requirements for a container, while in
the same time defining value_type as pair&lt;const Key, T&gt; - a type
that is not Assignable.
</p>

<p>
It should be noted that there exists a valid and non-contradictory
interpretation of the current text. The wording in 23.1/3 avoids 
mentioning value_type, referring instead to &quot;objects stored in a
container.&quot; One might argue that map does not store objects of
type map::value_type, but of map::mapped_type instead, and that the
Assignable requirement applies to map::mapped_type, not
map::value_type.
</p>

<p>
However, this makes map a special case (other containers store objects of
type value_type) and the Assignable requirement is needlessly restrictive in
general.
</p>

<p>
For example, the proposed resolution of active library issue 
<a href="lwg-defects.html#103" title="set::iterator is required to be modifiable, but this allows modification of keys (Status: CD1)">103</a><sup><a href="https://cplusplus.github.io/LWG/issue103" title="Latest snapshot">(i)</a></sup> is to make set::iterator a constant iterator; this
means that no set operations can exploit the fact that the stored
objects are Assignable.
</p>

<p>
This is related to, but slightly broader than, closed issue
<a href="lwg-closed.html#140" title="map&lt;Key, T&gt;::value_type does not satisfy the assignable requirement (Status: NAD Editorial)">140</a><sup><a href="https://cplusplus.github.io/LWG/issue140" title="Latest snapshot">(i)</a></sup>.
</p>


<p id="res-276"><b>Proposed resolution:</b></p>
<p>23.1/3: Strike the trailing part of the sentence:</p>
    <blockquote><p>
    , and the additional requirements of Assignable types from 23.1/3
    </p></blockquote>
<p>so that it reads:</p>
    <blockquote><p>
    -3- The type of objects stored in these components must meet the 
    requirements of CopyConstructible types (lib.copyconstructible).
    </p></blockquote>

<p>23.1/4: Modify to make clear that this requirement is not for all 
containers.  Change to:</p>

<blockquote><p>
-4- Table 64 defines the Assignable requirement.  Some containers 
require this property of the types to be stored in the container.  T is 
the type used to instantiate the container. t is a value of T, and u is 
a value of (possibly const) T.
</p></blockquote>

<p>23.1, Table 65: in the first row, change "T is Assignable" to "T is
CopyConstructible".</p>

<p>23.2.1/2: Add sentence for Assignable requirement.  Change to:</p>

<blockquote><p>
-2- A deque satisfies all of the requirements of a container and of a 
reversible container (given in tables in lib.container.requirements) and 
of a sequence, including the optional sequence requirements 
(lib.sequence.reqmts).  In addition to the requirements on the stored 
object described in 23.1[lib.container.requirements], the stored object 
must also meet the requirements of Assignable.  Descriptions are 
provided here only for operations on deque that are not described in one 
of these tables or for operations where there is additional semantic 
information.
</p></blockquote>

<p>23.2.2/2:  Add Assignable requirement to specific methods of list.  
Change to:</p>

<blockquote>
<p>-2- A list satisfies all of the requirements of a container and of a 
reversible container (given in two tables in lib.container.requirements) 
and of a sequence, including most of the the optional sequence 
requirements (lib.sequence.reqmts). The exceptions are the operator[] 
and at member functions, which are not provided. 

[Footnote: These member functions are only provided by containers whose 
iterators are random access iterators. --- end foonote]
</p>

<p>list does not require the stored type T to be Assignable unless the 
following methods are instantiated:

[Footnote: Implementors are permitted but not required to take advantage 
of T's Assignable properties for these methods. -- end foonote]
</p>
<pre>
     list&lt;T,Allocator&gt;&amp; operator=(const list&lt;T,Allocator&gt;&amp;  x );
     template &lt;class InputIterator&gt;
       void assign(InputIterator first, InputIterator last);
     void assign(size_type n, const T&amp; t);
</pre>


<p>Descriptions are provided here only for operations on list that are not 
described in one of these tables or for operations where there is 
additional semantic information.</p>
</blockquote>

<p>23.2.4/2:   Add sentence for Assignable requirement.  Change to:</p>

<blockquote><p>
-2- A vector satisfies all of the requirements of a container and of a 
reversible container (given in two tables in lib.container.requirements) 
and of a sequence, including most of the optional sequence requirements 
(lib.sequence.reqmts). The exceptions are the push_front and pop_front 
member functions, which are not provided.  In addition to the 
requirements on the stored object described in 
23.1[lib.container.requirements], the stored object must also meet the 
requirements of Assignable.  Descriptions are provided here only for 
operations on vector that are not described in one of these tables or 
for operations where there is additional semantic information.
</p></blockquote>


<p><b>Rationale:</b></p>
<p>list, set, multiset, map, multimap are able to store non-Assignables.
However, there is some concern about <code>list&lt;T&gt;</code>:
although in general there's no reason for T to be Assignable, some
implementations of the member functions <code>operator=</code> and
<code>assign</code> do rely on that requirement.  The LWG does not want
to forbid such implementations.</p>

<p>Note that the type stored in a standard container must still satisfy
the requirements of the container's allocator; this rules out, for
example, such types as "const int".  See issue <a href="lwg-defects.html#274" title="a missing/impossible allocator requirement (Status: CD1)">274</a><sup><a href="https://cplusplus.github.io/LWG/issue274" title="Latest snapshot">(i)</a></sup>
for more details.
</p>

<p>In principle we could also relax the "Assignable" requirement for
individual <code>vector</code> member functions, such as
<code>push_back</code>.  However, the LWG did not see great value in such
selective relaxation.  Doing so would remove implementors' freedom to
implement <code>vector::push_back</code> in terms of
<code>vector::insert</code>.</p>





</body>
</html>
