<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2158: Conditional copy&#47;move in std::vector</title>
<meta property="og:title" content="Issue 2158: Conditional copy&#47;move in std::vector">
<meta property="og:description" content="C++ library issue. Status: Open">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2158.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="2158"><a href="lwg-active.html#2158">2158</a>. Conditional copy&#47;move in <code>std::vector</code></h3>
<p><b>Section:</b> 23.3.13.3 <a href="https://wg21.link/vector.capacity">[vector.capacity]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a>
 <b>Submitter:</b> Nikolay Ivchenkov <b>Opened:</b> 2012-05-08 <b>Last modified:</b> 2022-11-06</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="lwg-index-open.html#vector.capacity">active issues</a> in [vector.capacity].</p>
<p><b>View all other</b> <a href="lwg-index.html#vector.capacity">issues</a> in [vector.capacity].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Open">Open</a> status.</p>
<p><b>Discussion:</b></p>

<p>
There are various operations on <code>std::vector</code> that can cause elements of the vector to be 
moved from one location to another. A move operation can use either rvalue or const lvalue as 
argument; the choice depends on the value of <code>!is_nothrow_move_constructible&lt;T&gt;::value &amp;&amp;
is_copy_constructible&lt;T&gt;::value</code>, where <code>T</code> is the element type. Thus, some operations 
on <code>std::vector</code> (e.g. 'resize' with single parameter, 'reserve', 'emplace_back') should have 
conditional requirements. For example, let's consider the requirement for 'reserve' in N3376 &ndash; 
23.3.13.3 <a href="https://wg21.link/vector.capacity">[vector.capacity]</a>&#47;2:
</p>
<blockquote><p>
<i>Requires</i>: <code>T</code> shall be <code>MoveInsertable</code> into <code>*this</code>.
</p></blockquote>
<p>
This requirement is not sufficient if an implementation is free to select copy constructor when 
<code>!is_nothrow_move_constructible&lt;T&gt;::value &amp;&amp; is_copy_constructible&lt;T&gt;::value</code> 
evaluates to true. Unfortunately, <code>is_copy_constructible</code> cannot reliably determine whether 
<code>T</code> is really copy-constructible. A class may contain public non-deleted copy constructor whose 
definition does not exist or cannot be instantiated successfully (e.g., 
<code>std::vector&lt;std::unique_ptr&lt;int&gt;&gt;</code> has copy constructor, but this type is not 
copy-constructible). Thus, the actual requirements should be:
</p>
<ul>
<li><p>
if <code>!is_nothrow_move_constructible&lt;T&gt;::value &amp;&amp; is_copy_constructible&lt;T&gt;::value</code> 
then <code>T</code> shall be <code>CopyInsertable</code> into <code>*this</code>;
</p></li>
<li><p>
otherwise <code>T</code> shall be <code>MoveInsertable</code> into <code>*this</code>.
</p></li>
</ul>
<p>
Maybe it would be useful to introduce a new name for such conditional requirement (in addition to 
"<code>CopyInsertable</code>" and "<code>MoveInsertable</code>").
</p>

<p><i>[2016-08 Chicago]</i></p>

<p>
The problem does not appear to be as severe as described. The <code>MoveInsertable</code>
requirements are consistently correct, but an issue may arise on the
exception-safety guarantees when we check for
<code>is_copy_constructible_v&lt;T&gt;</code>.  The problem, as described, is
typically for templates that appear to have a copy constructor, but one that
fails to compile once instantiated, and so gives a misleading result for the
trait.
</p>
<p>
In general, users should not provide such types, and the standard would not
serve users well by trying to address support for such types.  However, the
standard should not be providing such types either, such as
<code>vector&lt;unique_ptr&lt;T&gt;&gt;</code>.  A possible resolution would be
to tighten the constraints in Table 80 &mdash; Container Requirements, so that if
the Requirements for the copy constructor/assingment operator of a container
are not satisfied, that operation shall be deleted.
</p>
<p>
A futher problem highlighted by this approach is that there are no constraints on
the copy-assignment operator, so that <code>vector&lt;unique_ptr&lt;T&gt;&gt;</code>
should be <code>CopyAssignable</code>! However, we can lift the equivalent constraints from
the Allocator-aware container requirements.
</p>

<p><i>[08-2016, Chicago]</i></p>

<p>Fri PM: Move to Open</p>

<p><i>[2017-11 Albuquerque Saturday issues processing]</i></p>

<p>There's a bunch of uses of "shall" here that are incorrect. Also, CopyInsertable contains some semantic requirements, 
which can't be checked at compile time, so 'ill-formed' is not possible for detecting that.</p>

<p><i>[2018-06 Rapperswil Wednesday issues processing]</i></p>

<p>Daniel to provide updated wording.</p>

<p><i>[2018-06-12, Daniel provides revised wording]</i></p>


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

<p>
<table border="1">
<caption> 23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a> Table 80 &mdash; Container requirements </caption>
<tr>
  <td><b>Expression</b></td>
  <td><b>Return type</b></td>
  <td><b>Operational semantics</b></td>
  <td><b>Assertion/note/pre-/post-condition</b></td>
  <td><b>Complexity</b></td>
</tr>
<tr>
  <td><code>X(a)</code></td>
  <td></td>
  <td></td>
  <td>
    <i>Requires:</i> <code>T</code> is <code>CopyInsertable</code> into
    <code>X</code> (see below)<del>.</del><ins>, otherwise this expression shall be ill-formed.</ins><br/>
    post: <code>a == X(a)</code>.
  </td>
  <td>linear</td>
</tr>
<tr>
  <td><code>X u(a)</code><br/><code>X u = a;</code></td>
  <td></td>
  <td></td>
  <td>
    <i>Requires:</i> <code>T</code> is <code>CopyInsertable</code> into
    <code>X</code> (see below)<del>.</del><ins>, otherwise this expression shall be ill-formed.</ins><br/>
    post: <code>u == a</code>.
  </td>
  <td>linear</td>
</tr>
<tr>
  <td>...</td>
  <td>...</td>
  <td>...</td>
  <td>...</td>
  <td>...</td>
</tr>
<tr>
  <td><code>r = a</code></td>
  <td><code>X&amp;</code></td>
  <td></td>
  <td>
    <ins><i>Requires:</i> <code>T</code> is <code>CopyInsertable</code> into <code>X</code>
    and <code>CopyAssignable</code>, otherwise this expression shall be ill-formed.</ins><br/>
    post: <code>r == a</code>.</td>
  <td>linear</td>
</tr>
</table>
</p>

<p>
<table border="1">
<caption> 23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a> Table 83 &mdash; Allocator-aware container requirements </caption>
<tr>
  <td><b>Expression</b></td>
  <td><b>Return type</b></td>
  <td><b>Operational semantics</b></td>
  <td><b>Assertion/note/pre-/post-condition</b></td>
  <td><b>Complexity</b></td>
</tr>
<tr>
  <td><code>a = t</code></td>
  <td><code>X&amp;</code></td>
  <td></td>
  <td>
    <i>Requires:</i> <code>T</code> is <code>CopyInsertable</code> into <code>X</code> and
    <code>CopyAssignable</code><del>.</del><ins>, otherwise this  expression shall
    be ill-formed</ins><br/>
    post: <code>r == a</code>.</td>
  <td>linear</td>
</tr>
</table>
</p>
</blockquote>

<p><i>[2018-08-23 Batavia Issues processing. Priority to 3]</i></p>

<p>Changed <code>CopyInsertable</code> -&gt; <code>Cpp17CopyInsertable</code> in the resolution.</p>
<p>Tim says that the wording is not quite right &mdash; it imposes additional requirements.</p>


<p><i>[2022-11-06; Daniel comments]</i></p>

<p>
This issue has considerable overlap with LWG <a href="lwg-active.html#3758" title="Element-relocating operations of std::vector and std::deque 
should conditionally require Cpp17CopyInsertable in their preconditions (Status: New)">3758</a><sup><a href="https://cplusplus.github.io/LWG/issue3758" title="Latest snapshot">(i)</a></sup>.
</p>


<p id="res-2158"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4750">N4750</a>.
</p>

<blockquote class="note">
<p>
The revised wording below uses the new <i>Mandates:</i> element introduced by
adopting <a href="https://wg21.link/p0788r3">P0788R3</a> at the Rapperswil meeting 2018 
and which will become a new term of art with Jonathan's omnibus paper throughout the
Standard Library.
</p>
</blockquote>

<p>
<table border="1">
<caption> 23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a> Table 77 &mdash; Container requirements </caption>
<tr>
  <td><b>Expression</b></td>
  <td><b>Return type</b></td>
  <td><b>Operational semantics</b></td>
  <td><b>Assertion/note/pre-/post-condition</b></td>
  <td><b>Complexity</b></td>
</tr>
<tr>
  <td><code>X(a)</code></td>
  <td></td>
  <td></td>
  <td>
    <ins><i>Mandates:</i> Syntactic requirements of <code>T</code><br/> 
    is <code>Cpp17CopyInsertable</code> into <code>X</code> (see below).</ins><br/>
    <i>Requires:</i> <code>T</code> is <code>Cpp17CopyInsertable</code> into
    <code>X</code> <del>(see below)</del>.<br/>
    post: <code>a == X(a)</code>.
  </td>
  <td>linear</td>
</tr>
<tr>
  <td><code>X u(a)</code><br/><code>X u = a;</code></td>
  <td></td>
  <td></td>
  <td>
    <ins><i>Mandates:</i> Syntactic requirements of <code>T</code><br/> 
    is <code>Cpp17CopyInsertable</code> into <code>X</code> (see below).</ins><br/>
    <i>Requires:</i> <code>T</code> is <code>Cpp17CopyInsertable</code> into
    <code>X</code> <del>(see below)</del>.<br/>
    post: <code>u == a</code>.
  </td>
  <td>linear</td>
</tr>
<tr>
  <td>...</td>
  <td>...</td>
  <td>...</td>
  <td>...</td>
  <td>...</td>
</tr>
<tr>
  <td><code>r = a</code></td>
  <td><code>X&amp;</code></td>
  <td></td>
  <td>
    <ins><i>Mandates:</i> Syntactic requirements of <code>T</code><br/> 
    is <code>Cpp17CopyInsertable</code> into <code>X</code> (see below) and
    <code>CopyAssignable</code>.<br/></ins>
    <ins><i>Requires:</i> <code>T</code> is <code>Cpp17CopyInsertable</code> into <code>X</code>
    and <code>CopyAssignable</code>.</ins><br/>
    post: <code>r == a</code>.</td>
  <td>linear</td>
</tr>
</table>
</p>

<p>
<table border="1">
<caption> 23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a> Table 80 &mdash; Allocator-aware container requirements </caption>
<tr>
  <td><b>Expression</b></td>
  <td><b>Return type</b></td>
  <td><b>Operational semantics</b></td>
  <td><b>Assertion/note/pre-/post-condition</b></td>
  <td><b>Complexity</b></td>
</tr>
<tr>
  <td><code>a = t</code></td>
  <td><code>X&amp;</code></td>
  <td></td>
  <td>
    <ins><i>Mandates:</i> Syntactic requirements of <code>T</code> is<br/> 
    <code>Cpp17CopyInsertable</code> into <code>X</code> and <code>CopyAssignable</code>.<br/></ins>
    <i>Requires:</i> <code>T</code> is <code>Cpp17CopyInsertable</code> into <code>X</code> and
    <code>CopyAssignable</code>.<br/>
    post: <code>r == a</code>.</td>
  <td>linear</td>
</tr>
</table>
</p>






</body>
</html>
