title: Pass by value vs pass by rvalue reference
body: <p>When should I declare my function as:</p>
  
  <p><code>void foo(Widget w);</code></p>
  
  <p>as opposed to</p>
  
  <p><code>void foo(Widget&amp;&amp; w);</code>?</p>
  
  <p>Assume this is the only overload (as in, I pick one or the other, not both, and no other overloads). No templates involved. Assume that the function <code>foo</code> requires ownership of the <code>Widget</code> (e.g. <code>const Widget&amp;</code> is not part of this discussion). I'm not interested in any answer outside the scope of these circumstances. See addendum at end of post for <em>why</em> these constraints are part of the question.</p>
  
  <p>The primary difference that my colleagues and I can come up with is that the rvalue reference parameter forces you to be explicit about copies. The caller is responsible for making an explicit copy and then passing it in with <code>std::move</code> when you want a copy. In the pass by value case, the cost of the copy is hidden:</p>
  
  <pre><code>    //If foo is a pass by value function, calling + making a copy:
      Widget x{};
      foo(x); //Implicit copy
      //Not shown: continues to use x locally
  
      //If foo is a pass by rvalue reference function, calling + making a copy:
      Widget x{};
      //foo(x); //This would be a compiler error
      auto copy = x; //Explicit copy
      foo(std::move(copy));
      //Not shown: continues to use x locally
  </code></pre>
  
  <p>Other than that difference. Other than forcing people to be explicit about copying and changing how much syntactic sugar you get when calling the function, how else are these different? What do they say differently about the interface? Are they more or less efficient than one another?</p>
  
  <p>Other things that my colleagues and I have already thought of:</p>
  
  <ul>
  <li>The rvalue reference parameter means that you <em>may</em> move the argument, but does not mandate it. It is possible that the argument you passed in at the call site will be in its original state afterwards. It's also possible the function would eat/change the argument without ever calling a move constructor but assume that because it was an rvalue reference, the caller relinquished control. Pass by value, if you move into it, you must assume that a move happened; there's no choice.</li>
  <li>Assuming no elisions, a single move constructor call is eliminated with pass by rvalue.</li>
  <li>The compiler has better opportunity to elide copies/moves with pass by value. Can anyone substantiate this claim? Preferably with a link to gcc.godbolt.org showing optimized generated code from gcc/clang rather than a line in the standard. My attempt at showing this was probably not able to successfully isolate the behavior: <a href="https://godbolt.org/g/4yomtt">https://godbolt.org/g/4yomtt</a></li>
  </ul>
  
  <p><strong>Addendum:</strong> <em>why</em> am I constraining this problem so much?</p>
  
  <ul>
  <li>No overloads - if there were other overloads, this would devolve into a discussion of pass by value vs a set of overloads that include both const reference and rvalue reference, at which point the set of overloads is obviously more efficient and wins. This is well known, and therefore not interesting.</li>
  <li>No templates - I'm not interested in how forwarding references fit into the picture. If you have a forwarding reference, you call std::forward anyway. The goal with a forwarding reference is to pass things as you received them. Copies aren't relevant because you just pass an lvalue instead. It's well known, and not interesting.</li>
  <li><code>foo</code> requires ownership of <code>Widget</code> (aka no <code>const Widget&amp;</code>) - We're not talking about read-only functions. If the function was read-only or didn't need to own or extend the lifetime of the <code>Widget</code>, then the answer trivially becomes <code>const Widget&amp;</code>, which again, is well known, and not interesting. I also refer you to why we don't want to talk about overloads.</li>
  </ul>