Rvalue references

Jonathan M Davis newsgroup.d at jmdavisprog.com
Sun Jan 14 00:55:27 UTC 2018


On Friday, January 12, 2018 01:59:49 Tony via Digitalmars-d-learn wrote:
> On Monday, 8 January 2018 at 23:31:27 UTC, Jonathan M Davis wrote:
> > 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.
>
> What does it mean to "move" a variable/value instead of copying
> it?

It the simplest case, it means that the compiler does a bitwise copy rather
than a deep copy, but in other cases, it means that the compiler is able to
use the object in-place rather than creating a deep copy that it places
elsewhere. If you want to know more on the topic, you can always look into
C++ move constructors. They were added so that C++ could avoid a lot of
unnecessary copies. D took the approach of requiring that structs be
moveable (e.g. it's undefined behavior to have a struct contain a pointer to
itself), which simplifies things considerably.

You can also check out the stackoverflow questions that I linked to before:

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

They don't anwser what a move is, but they do give more context.

> Was "auto ref" created for anything besides structs?

auto ref works with any type whatsoever, but as far as efficiency goes, it's
kind of pointless for other types, because most everything else is at most
64 bits, which would be the size of a pointer on a 64-bit system. reals are
larger, and if we ever get cent and ucent, those would be larger, but most
stuff that isn't structs fits in 64 bits, meaning that copying them is not
expensive.

However, if you need to forward the refness of an argument, then auto ref
can still be critical - e.g. std.conv.emplace constructs an object in
memory, and if it couldn't pass the refness of the arguments on to the
constructor that it calls, then constructors with ref parameters wouldn't
work properly. Similarly, in templated code, you can have stuff like front
on a range which may or may not return by ref, so by using auto ref on the
return type of front when wrapping one range with another, the refness of
the underlying range's front can be passed along. Arguably, this aspect of
auto ref matters _way_ more than trying to make it more efficient to copy
structs.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list