<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 675: Move assignment of containers</title>
<meta property="og:title" content="Issue 675: Move assignment of containers">
<meta property="og:description" content="C++ library issue. Status: CD1">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue675.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="675"><a href="lwg-defects.html#675">675</a>. Move assignment of containers</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> Howard Hinnant <b>Opened:</b> 2007-05-05 <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>
James Hopkin pointed out to me that if <code>vector&lt;T&gt;</code> move assignment is O(1)
(just a <code>swap</code>) then containers such as <code>vector&lt;shared_ptr&lt;ostream&gt;&gt;</code> might have
the wrong semantics under move assignment when the source is not truly an rvalue, but a
moved-from lvalue (destructors could run late).
</p>

<blockquote><pre>
<code>vector&lt;shared_ptr&lt;ostream&gt;&gt;</code> v1;
<code>vector&lt;shared_ptr&lt;ostream&gt;&gt;</code> v2;
...
v1 = v2;               // #1
v1 = std::move(v2);    // #2
</pre></blockquote>

<p>
Move semantics means not caring what happens to the source (<code>v2</code> in this example).
It doesn't mean not caring what happens to the target (<code>v1</code>).  In the above example
both assignments should have the same effect on <code>v1</code>.  Any non-shared <code>ostream</code>'s
<code>v1</code> owns before the assignment should be closed, whether <code>v1</code> is undergoing
copy assignment or move assignment.
</p>

<p>
This implies that the semantics of move assignment of a generic container should be
<code>clear, swap</code> instead of just swap.  An alternative which could achieve the same
effect would be to move assign each element.  In either case, the complexity of move
assignment needs to be relaxed to <code>O(v1.size())</code>.
</p>

<p>
The performance hit of this change is not nearly as drastic as it sounds. 
In practice, the target of a move assignment has always just been move constructed
or move assigned <i>from</i>.  Therefore under <code>clear, swap</code> semantics (in
this common use case) we are still achieving O(1) complexity.
</p>



<p id="res-675"><b>Proposed resolution:</b></p>
<p>
Change 23.2 <a href="https://wg21.link/container.requirements">[container.requirements]</a>:
</p>

<blockquote>
<table border="1">
<caption>Table 89: Container requirements</caption>
<tr>
<th>expression</th><th>return type</th><th>operational semantics</th>
<th>assertion/note pre/post-condition</th><th>complexity</th>
</tr>
<tr>
<td><code>a = rv;</code></td><td><code>X&amp;</code></td>
<td>All existing elements of <code>a</code> are either move assigned or destructed</td>
<td><code>a</code> shall be equal to the 
value that <code>rv</code> had 
before this construction
</td>
<td><del>(Note C)</del> <ins>linear</ins></td>
</tr>
</table>

<p>
Notes: the algorithms <code>swap()</code>, <code>equal()</code> and
<code>lexicographical_compare()</code> are defined in clause 25. Those
entries marked "(Note A)" should have constant complexity. Those entries
marked "(Note B)" have constant complexity unless
<code>allocator_propagate_never&lt;X::allocator_type&gt;::value</code> is
<code>true</code>, in which case they have linear complexity.
<del>Those entries
marked "(Note C)" have constant complexity if <code>a.get_allocator() ==
rv.get_allocator()</code> or if either
<code>allocator_propagate_on_move_assignment&lt;X::allocator_type&gt;::value</code>
is <code>true</code> or
<code>allocator_propagate_on_copy_assignment&lt;X::allocator_type&gt;::value</code>
is <code>true</code> and linear complexity otherwise.</del>
</p>
</blockquote>



<p><i>[
post Bellevue Howard adds:
]</i></p>


<blockquote>
<p>
This issue was voted to WP in Bellevue, but accidently got stepped on by
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2525.pdf">N2525</a>
which was voted to WP simulataneously.  Moving back to Open for the purpose of getting
the wording right.  The intent of this issue and N2525 are not in conflict.
</p>
</blockquote>

<p><i>[
post Sophia Antipolis Howard updated proposed wording:
]</i></p>





</body>
</html>
