<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2164: What are the semantics of vector.emplace(vector.begin(), vector.back())?</title>
<meta property="og:title" content="Issue 2164: What are the semantics of vector.emplace(vector.begin(), vector.back())?">
<meta property="og:description" content="C++ library issue. Status: C++20">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2164.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++20">C++20</a> status.</em></p>
<h3 id="2164"><a href="lwg-defects.html#2164">2164</a>. What are the semantics of <code>vector.emplace(vector.begin(), vector.back())</code>?</h3>
<p><b>Section:</b> 23.3.13.5 <a href="https://wg21.link/vector.modifiers">[vector.modifiers]</a>, 23.2 <a href="https://wg21.link/container.requirements">[container.requirements]</a> <b>Status:</b> <a href="lwg-active.html#C++20">C++20</a>
 <b>Submitter:</b> Howard Hinnant <b>Opened:</b> 2012-07-07 <b>Last modified:</b> 2021-02-25</p>
<p><b>Priority: </b>2
</p>
<p><b>View all other</b> <a href="lwg-index.html#vector.modifiers">issues</a> in [vector.modifiers].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++20">C++20</a> status.</p>
<p><b>Discussion:</b></p>

<p>
Nikolay Ivchenkov recently brought the following example on the
<a href="https://groups.google.com/a/isocpp.org/d/topic/std-discussion/dhy23mDFXj4/discussion">std-discussion</a> 
newsgroup, asking whether the following program well-defined:
</p>
<blockquote><pre>
#include &lt;iostream&gt;
#include &lt;vector&gt;

int main()
{
  std::vector&lt;int&gt; v;
  v.reserve(4);
  v = { 1, 2, 3 };
  v.emplace(v.begin(), v.back());
  for (int x : v)
    std::cout &lt;&lt; x &lt;&lt; std::endl;
}
</pre></blockquote>
<p>
Nikolay Ivchenkov:
<p/>
I think that an implementation of <code>vector</code>'s 'emplace' should initialize an intermediate object with 
<code>v.back()</code> before any shifts take place, then perform all necessary shifts and finally replace the 
value pointed to by <code>v.begin()</code> with the value of the intermediate object. So, I would expect the 
following output:
</p>
<blockquote><pre>
3
1
2
3
</pre></blockquote>
<p>
GNU C++ 4.7.1 and GNU C++ 4.8.0 produce other results:
</p>
<blockquote><pre>
2
1
2
3
</pre></blockquote>
<p>
Howard Hinnant:
<p/>
I believe Nikolay is correct that vector should initialize an intermediate object with <code>v.back()</code> 
before any shifts take place. As Nikolay pointed out in another email, this appears to be the only way to 
satisfy the strong exception guarantee when an exception is not thrown by <code>T</code>'s copy constructor, 
move constructor, copy assignment operator, or move assignment operator as specified by 
23.3.13.5 <a href="https://wg21.link/vector.modifiers">[vector.modifiers]</a>/p1. I.e. if the emplace construction throws, the vector must remain unaltered.
<p/>
That leads to an implementation that tolerates objects bound to the function parameter pack of the <code>emplace</code> 
member function may be elements or sub-objects of elements of the container.
<p/>
My position is that the standard is correct as written, but needs a clarification in this area. Self-referencing 
<code>emplace</code> should be legal and give the result Nikolay expects. The proposed resolution of LWG <a href="lwg-closed.html#760" title="The emplace issue (Status: NAD)">760</a><sup><a href="https://cplusplus.github.io/LWG/issue760" title="Latest snapshot">(i)</a></sup> 
is not correct.
</p>

<p><i>[2015-02 Cologne]</i></p>

<p>
LWG agrees with the analysis including the assessment of LWG <a href="lwg-closed.html#760" title="The emplace issue (Status: NAD)">760</a><sup><a href="https://cplusplus.github.io/LWG/issue760" title="Latest snapshot">(i)</a></sup> and would appreciate a concrete wording proposal.
</p>

<p><i>[2015-04-07 dyp comments]</i></p>

<p>
The Standard currently does not require that creation of such
intermediate objects is legal. 23.2.4 <a href="https://wg21.link/sequence.reqmts">[sequence.reqmts]</a> Table 100
&mdash; "Sequence container requirements" currently specifies:
</p>

<blockquote>
<table border="1">
<caption>Table 100 &mdash; Sequence container requirements</caption>
<tr>
<th>Expression</th>
<th>Return type</th>
<th>Assertion&#47;note<br/>pre-&#47;post-condition</th>
</tr>

<tr>
<td colspan="3" align="center">
<code>&hellip;</code>
</td>
</tr>

<tr>
<td>
<code>a.emplace(p, args);</code>
</td>
<td>
<code>iterator</code>
</td>
<td>
<i>Requires</i>: <code>T</code> is <code>EmplaceConstructible</code> into
<code>X</code> from <code>args</code>. For <code>vector</code> and <code>deque</code>,
<code>T</code> is also <code>MoveInsertable</code> into <code>X</code> and
<code>MoveAssignable</code>. [&hellip;]
</td>
</tr>

<tr>
<td colspan="3" align="center">
<code>&hellip;</code>
</td>
</tr>

</table>
</blockquote>

<p>
The <code>EmplaceConstructible</code> concept is defined via
<code>allocator_traits&lt;A&gt;::construct</code> in 23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a> p15.5 That's surprising to me
since the related concepts use the suffix <code>Insertable</code> if they
refer to the allocator. An additional requirement such as
<code>std::is_constructible&lt;T, Args...&gt;</code> is necessary to allow
creation of intermediate objects.
</p>

<p>
The creation of intermediate objects also affects other functions, such
as <code>vector.insert</code>. Since aliasing the vector is only allowed for
the single-element forms of <code>insert</code> and <code>emplace</code> (see
<a href="lwg-closed.html#526" title="Is it undefined if a function in the standard changes in parameters? (Status: NAD)">526</a><sup><a href="https://cplusplus.github.io/LWG/issue526" title="Latest snapshot">(i)</a></sup>), the range-forms are not affected. Similarly,
aliasing is not allowed for the rvalue-reference overload. See also LWG
<a href="lwg-defects.html#2266" title="vector and deque have incorrect insert requirements (Status: C++17)">2266</a><sup><a href="https://cplusplus.github.io/LWG/issue2266" title="Latest snapshot">(i)</a></sup>.
</p>

<p>
There might be a problem with a requirement of
<code>std::is_constructible&lt;T, Args...&gt;</code> related to the issues
described in LWG <a href="lwg-active.html#2461" title="Interaction between allocators and container exception safety guarantees (Status: New)">2461</a><sup><a href="https://cplusplus.github.io/LWG/issue2461" title="Latest snapshot">(i)</a></sup>. For example, a scoped allocator
adapter passes additional arguments to the constructor of the value
type. This is currently not done in recent implementations of libstdc++
and libc++ when creating the intermediate objects, they simply create
the intermediate object by perfectly forwarding the arguments. If such
an intermediate object is then moved to its final destination in the
vector, a change of the allocator instance might be required &mdash;
potentially leading to an expensive copy. One can also imagine worse
problems, such as run-time errors (allocators not comparing equal at
run-time) or compile-time errors (if the value type cannot be created
without the additional arguments). I have not looked in detail into this
issue, but I'd be reluctant adding a requirement such as
<code>std::is_constructible&lt;T, Args...&gt;</code> without further
investigation.
</p>

<p>
It should be noted that the creation of intermediate objects currently
is inconsistent in libstdc++ vs libc++. For example, libstdc++ creates
an intermediate object for <code>vector.insert</code>, but not
<code>vector.emplace</code>, whereas libc++ does the exact opposite in this
respect.
</p>

<p>
A live demo of the inconsistent creation of intermediate objects can be
found <a href="http://coliru.stacked-crooked.com/a/449253d3d329ef4c">here</a>.
</p>

<p><i>[2015-10, Kona Saturday afternoon]</i></p>

<p>HH: If it were easy, it'd have wording. Over the decades I have flipped 180 degrees on this. My current position is that it should work even if the element is in the same container.</p>
<p>TK: What's the implentation status? JW: Broken in GCC. STL: Broken in MSVS. Users complain about this every year.</p>
<p>MC: 526 says push_back has to work.</p>
<p>HH: I think you have to make a copy of the element anyway for reasons of exception safety. [Discussion of exception guarantees] </p>
<p>STL: vector has strong exception guarantees. Could we not just provide the Basic guarantee here. </p>
<p>HH: It would terrify me to relax that guarantee. It'd be an ugly, imperceptible runtime error. </p>
<p>HH: I agree if we had a clean slate that strong exception safety is costing us here, and we shouldn't provide it if it costs us.</p>
<p>STL: I have a mail here, "how can vector provide the strong guarantee when inserting in the middle". </p>
<p>HH: The crucial point is that you only get the strong guarantee if the exception is thrown by something other than the copy and move operations that are used to make the hole. </p>
<p>STL: I think we need to clean up the wording. But it does mandate currently that the self-emplacement must work, because nothings says that you can't do it. TK clarifies that a) self-emplacement must work, and b) you get the strong guarantee only if the operations for making the hole don't throw, otherwise basic. HH agrees. STL wants this to be clear in the Standard.</p>
<p>STL: Should it work for deque, too? HH: Yes.</p>
<p>HH: I will attempt wording for this. </p>
<p>TK: Maybe mail this to the reflector, and maybe someone has a good idea? </p>
<p>JW: I will definitely not come up with anything better, but I can critique wording.</p>
<p>Moved to Open; Howard to provide wording, with feedback from Jonathan.</p>

<p><i>[2017-01-25, Howard suggests wording]</i></p>


<p><i>[2018-1-26 issues processing telecon]</i></p>

<p>Status to 'Tentatively Ready' after adding a period to Howard's wording.</p>

<p><i>[2018-3-17 Adopted in Jacksonville]</i></p>



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

<ol>
<li><p>Modify in 23.2.4 <a href="https://wg21.link/sequence.reqmts">[sequence.reqmts]</a> Table 87 &mdash; "Sequence container requirements" as indicated:</p>

<blockquote>
<table border="1">
<caption>Table 87 &mdash; Sequence container requirements (in addition to container)</caption>
<tr>
<th>Expression</th>
<th>Return type</th>
<th>Assertion&#47;note<br/>pre-&#47;post-condition</th>
</tr>
<tr>
<td colspan="3" align="center">
<code>[&hellip;]</code>
</td>
</tr>
<tr>
<td>
<code>a.emplace(p, args)</code>
</td>
<td><code>iterator</code></td>
<td>
<i>Requires</i>: <code>T</code> is <code>EmplaceConstructible</code> into <code>X</code><br/>
from <code>args</code>. For <code>vector</code> and <code>deque</code>, <code>T</code> is also<br/>
<code>MoveInsertable</code> into <code>X</code> and <code>MoveAssignable</code>.<br/>
<i>Effects:</i> Inserts an object of type <code>T</code><br/>
constructed with<br/>
<code>std::forward&lt;Args&gt;(args)...</code> before <code>p</code>.<br/>
<ins>[<i>Note:</i> <code>args</code> may directly or indirectly refer to a value<br/> 
in <code>a</code>. &mdash; <i>end note</i>]</ins>
</td>
</tr>
</table>
</blockquote>
</li>
</ol>





</body>
</html>
