<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml">
 <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
 </head>
 <body>
  <p id="mceDummy" style="margin: 0;">On 10 April 2012 at 09:06 Andrei Alexandrescu <andrei@erdani.com> wrote:</p>
  <div id="mcePresetContent" style="margin: 5px 0px 5px 0px;" class="mceHTML">
   <br/>
   > On 4/10/12 1:28 AM, Walter Bright wrote:
   <br/>
   > > Let's say the compiler auto-generates the following:
   <br/>
   > >
   <br/>
   > > void foo(T t) { foo(t); }
   <br/>
   > >
   <br/>
   > > in case it sees:
   <br/>
   > >
   <br/>
   > > void foo(ref T t) { ... }
   <br/>
   > >
   <br/>
   > > I don't think that's a solution at all. It's just a roundabout way for
   <br/>
   > > the compiler to generate a temporary anyway. Nothing has been gained.
   <br/>
   >
   <br/>
   > I agree.
   <br/>
   >
   <br/>
   > To answer the question about why rvalue -> const& has been a mistake in
   <br/>
   > C++: the history is, C++ had trouble with defining copy constructors.
   <br/>
   > The simple idea would be
   <br/>
   >
   <br/>
   > T(T source);
   <br/>
   >
   <br/>
   > but this didn't quite work because of the infinite regression:
   <br/>
   >
   <br/>
   > T a;
   <br/>
   > T b(a); // recurses forever
   <br/>
   >
   <br/>
   > Going with
   <br/>
   >
   <br/>
   > T(T& source);
   <br/>
   >
   <br/>
   > would make this code nonworking:
   <br/>
   >
   <br/>
   > T fun();
   <br/>
   > T a(fun());
   <br/>
   >
   <br/>
   > because C++ does not allow rvalue to modifiable conversion on
   <br/>
   > correctness grounds.
   <br/>
   >
   <br/>
   > Now, the solution C++ chose to solve this was to make const& a universal
   <br/>
   > sink for rvalues, modifiable lvalues, and const lvalues altogether, and
   <br/>
   > the copy constructor became:
   <br/>
   >
   <br/>
   > T(const T&);
   <br/>
   >
   <br/>
   > That solves the infinite regression nicely but at the cost of
   <br/>
   > introducing an unnatural conversion rule that ultimately disabled this code:
   <br/>
   >
   <br/>
   > void fun(T);
   <br/>
   > void fun(T&);
   <br/>
   > void fun(const T&);
   <br/>
   >
   <br/>
   > The mechanisms through which these overloads were deemed illegal are
   <br/>
   > complex and non-obvious; practically it was a sheer consequence of the
   <br/>
   > fact that overloading rules were already difficult and nobody figured
   <br/>
   > that the rvalue overload was necessary, so it fell by the wayside.
   <br/>
   >
   <br/>
   > (We've seen similar subtle issues arising with hashtables - Teoh tried
   <br/>
   > to put hashes in a library and hit a maze of subtle special cases that
   <br/>
   > work for the built-in type but not for library one simply because no
   <br/>
   > attention was paid to that.)
   <br/>
   >
   <br/>
   > So now C++98 got standardized, and before long it was clear that
   <br/>
   > unnecessary copies were a large liability. It was, however, impossible
   <br/>
   > to introduce a new overload rule without breaking some code that counted
   <br/>
   > on it. That prompted the entire rvalue references work, which is a maze
   <br/>
   > of rules and special cases designed to navigate the wreck created by the
   <br/>
   > rvalue -> const& trivial conversion.
   <br/>
   >
   <br/>
   >
   <br/>
   > Andrei
  </div>
  <p style="margin: 0px;"> </p>
  <p style="margin: 0px;">Thanks for explaining; I've wondered about this several times.  Also, it seems some compiler vendors are having trouble implementing const& efficiently:</p>
  <p style="margin: 0px;"> </p>
  <p style="margin: 0px;">
   <a href="https://askldjd.wordpress.com/2010/05/08/const-reference-to-temporary-is-useless/">https://askldjd.wordpress.com/2010/05/08/const-reference-to-temporary-is-useless/</a>
  </p>
  <p style="margin: 0px;"> </p>
  <p style="margin: 0px;">(The comments also have a bit of useful info.)</p>
  <p style="margin: 0px;"> </p>
  <p style="margin: 0px;">-Lars</p>
 </body>
</html>