[dmd-beta] D 2.059 beta 4
Andrei Alexandrescu
andrei at erdani.com
Tue Apr 10 00:06:13 PDT 2012
On 4/10/12 1:28 AM, Walter Bright wrote:
> Let's say the compiler auto-generates the following:
>
> void foo(T t) { foo(t); }
>
> in case it sees:
>
> void foo(ref T t) { ... }
>
> I don't think that's a solution at all. It's just a roundabout way for
> the compiler to generate a temporary anyway. Nothing has been gained.
I agree.
To answer the question about why rvalue -> const& has been a mistake in
C++: the history is, C++ had trouble with defining copy constructors.
The simple idea would be
T(T source);
but this didn't quite work because of the infinite regression:
T a;
T b(a); // recurses forever
Going with
T(T& source);
would make this code nonworking:
T fun();
T a(fun());
because C++ does not allow rvalue to modifiable conversion on
correctness grounds.
Now, the solution C++ chose to solve this was to make const& a universal
sink for rvalues, modifiable lvalues, and const lvalues altogether, and
the copy constructor became:
T(const T&);
That solves the infinite regression nicely but at the cost of
introducing an unnatural conversion rule that ultimately disabled this code:
void fun(T);
void fun(T&);
void fun(const T&);
The mechanisms through which these overloads were deemed illegal are
complex and non-obvious; practically it was a sheer consequence of the
fact that overloading rules were already difficult and nobody figured
that the rvalue overload was necessary, so it fell by the wayside.
(We've seen similar subtle issues arising with hashtables - Teoh tried
to put hashes in a library and hit a maze of subtle special cases that
work for the built-in type but not for library one simply because no
attention was paid to that.)
So now C++98 got standardized, and before long it was clear that
unnecessary copies were a large liability. It was, however, impossible
to introduce a new overload rule without breaking some code that counted
on it. That prompted the entire rvalue references work, which is a maze
of rules and special cases designed to navigate the wreck created by the
rvalue -> const& trivial conversion.
Andrei
More information about the dmd-beta
mailing list