rvalue references
Diggory
diggsey at googlemail.com
Fri Apr 26 14:21:49 PDT 2013
> You're just asking for bugs if you allow ref to accept rvalues.
> We've had problems like this before when some literals were
> treated as lvalues. The behavior of a function which takes its
> argument by ref and the behavior of one which takes its
> argument by auto ref are fundamentally different.
The only purpose of rvalue references is to allow the callee to
mutate the value... Otherwise you would just use a const ref.
In C++ you can do this:
void foo(const int& p) {
}
int bar() { return 1; }
foo(1); // literals pass just fine by const reference
foo(bar()) // and r-values...
The only reason for r-value references is to implement move
semantics (which means completely destroying the original value,
and I think that counts as "mutating" it)
And the only reason r-value references have a different syntax is
so that you can override your function and provide two
implementations: one which accepts rvalue references and is
destructive, and the other which accept const references and
makes a copy.
The reason normal references couldn't be used in C++ is that
normal non-const lvalues would cause the destructive overload to
be called by default rather than the non-destructive one because
they convert to "T&" more easily than "const T&", and the desired
behaviour is that for lvalues "move" semantics must be explicit
to prevent surprises.
An alternative I am in favour of is just to give the conversion
to "const T&" a higher priority than the conversion to "T&" for
lvalues, so that overloads that take both will normally choose
the non-destructive one. To explicitly use the destructive form
one can just explicitly cast to "T&" or call a helper function
"T& move(T&)" which just makes the syntax nicer.
In D this would obviously be "ref const(T)" and "ref T" instead
but the same ideas apply.
More information about the Digitalmars-d
mailing list