Rvalue references

Jonathan M Davis newsgroup.d at jmdavisprog.com
Mon Jan 8 23:31:27 UTC 2018


On Monday, January 08, 2018 23:07:52 Jiyan via Digitalmars-d-learn wrote:
> Sry i know i asked it already in IRC:
> Are rvalue references already solved with auto ref?
>
> https://p0nce.github.io/d-idioms/#Rvalue-references:-Understanding-auto-re
> f-and-then-not-using-it
>
> Says rvalues are moved!
>
> The other solution seems not so practical.

rvalue references do not exist in D. auto ref makes it so that the refness
of a parameter or return type of a templated function depends on whether
its' an lvalue or rvalue. e.g.

auto foo(T)(auto ref T t)
{
    return t;
}

foo(42);

will result in foo being instantiated as

int foo(int t)
{
    return t;
}

whereas

int i;
foo(i);

will result in foo being instantiated as

int foo(ref int t)
{
    return t;
}

So, by using auto ref, a function can accept both lvalues and rvalues. And
in D, rvalues get moved, not copied.

https://stackoverflow.com/questions/35120474/does-d-have-a-move-constructor
https://stackoverflow.com/questions/6884996/questions-about-postblit-and-move-semantics

> Is any solution to them intended, or was all the talk about
> rvalue references simply discarded?

Andrei has said on a number of occasions that he does not want rvalue
references in D, and as I understand it, he considers them to have been a
mistake in C++. There has been occasional talk of defining a way to have ref
(or something similar to ref) accept rvalues in addition to lvalues, but it
would have to be done in a way that would satisfy Andrei and his concern
about rvalue references. I don't know what that would look like, and thus
far, no one has create a DIP for such a feature.

I think that the solution that most folks have gone with is simply passing
everything by value unless it needs to be passed by ref so that the argument
can be mutated. And then if profiling indicates that that's a performance
problem in a particular case, then auto ref gets used, or the function gets
overloaded on refness, or the code is refactored in some other way such that
it's not passing around an object that is expensive to copy, or the object
is turned into a reference type.

The fact that D moves rvalues tends to mean that the only cases where
expensive copying would be a problem are with large objects passed as
lvalues or with objects with expensive postblits which are passed by value
(and expensive postblits are generally discouraged). But the most efficient
thing to do there depends on the code and how it interacts with the
optimizer such that assuming what's going to be more efficient can often be
wrong (especially if the object is smaller). In most cases, worrying about
excessive copying seems to tend to be a premature optimization, though if an
object is particularly large, then odds are it should probably be a
reference type. Either way, in most cases, I'd suggest not worrying all that
much about the cost of copying objects unless you have evidence that it's
actually a problem with your code, and when it is, that usually means that
using a reference type would be better, but auto ref is there for those
cases where it makes sense to templatize a function on refness to pass
objects more efficiently (or simply for when refness needs to be passed on
for one reason or another).

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list