Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The syntactic form <code>T&amp;&amp;</code> <em>in the context of type deduction</em> (which includes <em>template argument deduction</em>, but for instance also the deduction of the type of a variable declared as <code>auto</code>) does <em>not</em> indicate an rvalue reference, but rather what Scott Meyers calls a [<em>universal reference</em>]. Please notice, that only the very particular <em>syntactic form</em> <code>T&amp;&amp;</code> denotes a universal reference, while other, similar forms are not regarded as such. For instance:</p> <pre><code>template&lt;typename T&gt; void foo(T&amp;&amp; t); &lt;-- T&amp;&amp; is a universal reference template&lt;typename T&gt; void foo(T const&amp;&amp; t); &lt;-- T const&amp;&amp; is NOT a universal reference template&lt;typename T&gt; void foo(S&lt;T&gt;&amp;&amp; t); &lt;-- S&lt;T&gt;&amp;&amp; is NOT a universal reference template&lt;typename T&gt; struct S { void foo(T&amp;&amp; t); }; &lt;-- T&amp;&amp; is NOT a universal reference </code></pre> <p>Universal references can bind both to lvalues and to rvalues. If an lvalue of type <code>A</code> is bound, then <code>T</code> is deduced to be <code>A&amp;</code> and the type of the argument resolves into <code>A&amp;</code> (lvalue reference) due to the rule of <em>reference collapsing</em> (<code>A&amp; &amp;&amp;</code> becomes <code>A&amp;</code>). If an rvalue of type <code>A</code> is bound, then <code>T</code> is deduced to be <code>A</code> and the type of the argument resolves into <code>A&amp;&amp;</code> (rvalue reference).</p> <p>[<strong>Note</strong>: <em>Reference collapsing rule might seem complicated, but they are actually quite easy: to quote Stephan T. Lavavej, "lvalue references are contagious", meaning that when the forms <code>T&amp;&amp; &amp;</code>, <code>T&amp; &amp;</code>, or <code>T&amp; &amp;&amp;</code> get instantiated, they always resolve into <code>T&amp;</code> - only the form <code>T&amp;&amp; &amp;&amp;</code> is resolved into <code>T&amp;&amp;</code></em>]</p> <p>This is why the <code>std::move</code> function template will be instantiated as follows when the argument is an <strong>lvalue</strong> (<code>T</code> is deduced to be <code>T&amp;</code>):</p> <pre><code>typename remove_reference&lt;A&amp;&gt;::type&amp;&amp; std::move(A&amp; &amp;&amp; a); </code></pre> <p>while it will be instantiated as follows when the argument is an <strong>rvalue</strong> (<code>T</code> is deduced to be <code>A</code>)</p> <pre><code>typename remove_reference&lt;A&gt;::type&amp;&amp; std::move(A&amp;&amp; a); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload