Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>Guideline</strong>:</p> <p>Do not overload:</p> <pre><code>template &lt;typename T&gt; void f(T&amp;) {} template &lt;typename T&gt; void f(T&amp;&amp;) {} </code></pre> <p><strong>Reason</strong>:</p> <p>There is a special template deduction rule for the pattern:</p> <pre><code>template &lt;typename T&gt; void f(T&amp;&amp;) {} </code></pre> <p>This rule exists in order to enable so called "perfect forwarding". It helps things like <code>bind</code> and <code>make_shared</code> forward their arguments perfectly, preserving both cv-qualifiers and "value category" (lvalue/rvalue-ness).</p> <p>This special rule says that when <code>f(T&amp;&amp;)</code> is called with an lvalue parameter (e.g. <code>int</code>), that T gets deduced as an lvalue reference (e.g. <code>int&amp;</code>) instead of <code>int</code>. And an rvalue reference to lvalue reference to int collapses down to just lvalue reference to int. I.e.</p> <pre><code>f(x) </code></pre> <p>calls</p> <pre><code>f&lt;int&amp;&gt;(int&amp; &amp;&amp; x); </code></pre> <p>which simplifies to:</p> <pre><code>f&lt;int&amp;&gt;(int&amp; x); </code></pre> <p><em>Edit</em></p> <p><del>This is not more or less specialized than <code>f&lt;int&gt;(int&amp;)</code>.</del></p> <p>Thanks to Johannes Schaub for the correction (see comments).</p> <p><strong>Solution</strong>:</p> <p>You can do whatever you want with the single function:</p> <pre><code>template &lt;typename T&gt; void f(T&amp;&amp;) {} </code></pre> <p>If <code>T</code> deduces as an lvalue reference, do whatever you wanted to do in your first overload, otherwise do whatever you wanted to do in your second overload:</p> <pre><code>template &lt;class T&gt; void f_imp(T&amp;, std::true_type) {std::cout &lt;&lt; "lvalue\n";} template &lt;class T&gt; void f_imp(T&amp;&amp;, std::false_type) {std::cout &lt;&lt; "rvalue\n";} template &lt;typename T&gt; void f(T&amp;&amp; x) { f_imp(std::forward&lt;T&gt;(x), std::is_lvalue_reference&lt;T&gt;()); } </code></pre> <p>And use <code>std::forward</code> to perfectly forward <code>x</code> to the implementation-detail function.</p>
    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.
    3. VO
      singulars
      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