<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2509: [fund.ts.v2] any_cast doesn't work with rvalue reference targets and cannot move with a value target</title>
<meta property="og:title" content="Issue 2509: [fund.ts.v2] any_cast doesn't work with rvalue reference targets and cannot move with a value target">
<meta property="og:description" content="C++ library issue. Status: TS">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2509.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#TS">TS</a> status.</em></p>
<h3 id="2509"><a href="lwg-defects.html#2509">2509</a>. [fund.ts.v2] <code>any_cast</code> doesn't work with rvalue reference targets and cannot move with a value target</h3>
<p><b>Section:</b> 6.4 <a href="https://cplusplus.github.io/fundamentals-ts/v2.html#any.nonmembers">[fund.ts.v2::any.nonmembers]</a> <b>Status:</b> <a href="lwg-active.html#TS">TS</a>
 <b>Submitter:</b> Ville Voutilainen <b>Opened:</b> 2015-06-13 <b>Last modified:</b> 2017-07-30</p>
<p><b>Priority: </b>2
</p>
<p><b>View all issues with</b> <a href="lwg-status.html#TS">TS</a> status.</p>
<p><b>Discussion:</b></p>
<p><b>Addresses: fund.ts.v2</b></p>
<p>
In <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html">Library Fundamentals v1</a>, 
[any.nonmembers]/5 says:
</p>
<blockquote><p>
For the first form, <code>*any_cast&lt;add_const_t&lt;remove_reference_t&lt;ValueType&gt;&gt;&gt;(&amp;operand)</code>. 
For the second and third forms, <code>*any_cast&lt;remove_reference_t&lt;ValueType&gt;&gt;(&amp;operand)</code>.
</p></blockquote>
<ol>
<li><p>This means that</p>
<blockquote><pre>
any_cast&lt;Foo&amp;&amp;&gt;(<i>whatever_kind_of_any_lvalue_or_rvalue</i>);
</pre></blockquote>
<p>
is always ill-formed.  That's unfortunate, because forwarding such a cast
result of an <code>any</code> is actually useful, and such uses do not want to copy/move
the underlying value just yet.
</p>
</li>

<li><p>Another problem is that that same specification prevents an implementation
from moving to the target when</p>
<blockquote><pre>
ValueType any_cast(any&amp;&amp; operand);
</pre></blockquote>
<p>
is used. The difference is observable, so an implementation can't perform
an optimization under the as-if rule. We are pessimizing every <code>CopyConstructible</code>
<em>and</em> <code>MoveConstructible</code> type because we are not using the move when
we can. This unfortunately includes types such as the library containers,
and we do not want such a pessimization!
</p>
</li>
</ol>

<p><i>[2015-07, Telecon]</i></p>

<p>Jonathan to provide wording</p>

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

<p>Eric offered to help JW with wording</p>
<p>Move to Open</p>

<p><i>[2016-01-30, Ville comments and provides wording]</i></p>

<p>
Drafting note: the first two changes add support for types that have
explicitly deleted move constructors. Should we choose not to support
such types at all, the third change is all we need. For the second change,
there are still potential cases where <i>Requires</i> is fulfilled but <i>Effects</i>
is ill-formed, if a suitably concocted type is thrown into the mix.
</p>


<p id="res-2509"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html">N4562</a>.
</p>

<ol>
<li><p>In 6.3.1 <a href="https://cplusplus.github.io/fundamentals-ts/v2.html#any.cons">[fund.ts.v2::any.cons]</a> p11+p12, edit as follows:</p>
<blockquote>
<pre>
template&lt;class ValueType&gt;
  any(ValueType&amp;&amp; value);
</pre>
<blockquote>
<p>
-10- Let <code>T</code> be equal to <code>decay_t&lt;ValueType&gt;</code>.
<p/>
-11- <i>Requires</i>: <code>T</code> shall satisfy the <code>CopyConstructible</code> requirements<ins>, except for the requirements 
for <code>MoveConstructible</code></ins>. If <code>is_copy_constructible_v&lt;T&gt;</code> is <code>false</code>, the program is ill-formed.
<p/>
-12- <i>Effects</i>: <ins>If <code>is_constructible_v&lt;T, ValueType&amp;&amp;&gt;</code> is true, c</ins><del>C</del>onstructs 
an object of type <code>any</code> that contains an object of type <code>T</code> direct-initialized with 
<code>std::forward&lt;ValueType&gt;(value)</code>. <ins>Otherwise, constructs an object of type <code>any</code> that contains an object of 
type <code>T</code> direct-initialized with <code>value</code>.</ins>
<p/>
[&hellip;]
</p>
</blockquote>
</blockquote>
</li>

<li><p>In 6.4 <a href="https://cplusplus.github.io/fundamentals-ts/v2.html#any.nonmembers">[fund.ts.v2::any.nonmembers]</a> p5, edit as follows:</p>
<blockquote>
<pre>
template&lt;class ValueType&gt;
  ValueType any_cast(const any&amp; operand);
template&lt;class ValueType&gt;
  ValueType any_cast(any&amp; operand);
template&lt;class ValueType&gt;
  ValueType any_cast(any&amp;&amp; operand);
</pre>
<blockquote>
<p>
-4- <i>Requires</i>: <code>is_reference_v&lt;ValueType&gt;</code> is <code>true</code> or <code>is_copy_constructible_v&lt;ValueType&gt;</code> 
is <code>true</code>. Otherwise the program is ill-formed. 
<p/>
-5- <i>Returns</i>: For the first form, <code>*any_cast&lt;add_const_t&lt;remove_reference_t&lt;ValueType&gt;&gt;&gt;(&amp;operand)</code>. 
For the second <del>and third</del> form<del>s</del>, <code>*any_cast&lt;remove_reference_t&lt;ValueType&gt;&gt;(&amp;operand)</code>. 
<ins>For the third form, if <code>is_move_constructible_v&lt;ValueType&gt;</code> is <code>true</code> and
<code>is_lvalue_reference_v&lt;ValueType&gt;</code> is <code>false</code>, 
<code>std::move(*any_cast&lt;remove_reference_t&lt;ValueType&gt;&gt;(&amp;operand))</code>, otherwise,
<code>*any_cast&lt;remove_reference_t&lt;ValueType&gt;&gt;(&amp;operand)</code>.</ins>
<p/>
[&hellip;]
</p>
</blockquote>
</blockquote>
</li>
</ol>





</body>
</html>
