<!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>