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