On Friday, 2 May 2014 at 21:29:51 UTC, Mark Isaacson wrote:
Auto ref parameters seem to be just what I need. Thanks! I'd
still be curious if anyone has additional information regarding
the rationale at play (I'm spoiled, reading TDPL and having
each decision explained in text).
I had the impression that your goal was to avoid copying. I
didn't write it explicitly, but `auto ref` doesn't do that. It
just allows you to avoid writing the same function twice, once
with ref, and once without. It is essentially equivalent to this:
void fun(ref const int x) {
// Stuff
}
void fun(const int x) {
// Stuff
}
This means that you will still get a (bit-wise) copy if you pass
in an r-value. But semantically, this is a move, not a copy, so
it is potentially cheaper than a copy (if your type has an
expensive postblit). You can see this from the following little
test program:
import std.stdio;
struct S {
this(this) {
writefln("postblit %x", &this);
}
~this() {
writefln("destructor %x", &this);
}
}
void fun()(auto ref const S x) {
writefln("fun: &x = %x", &x);
}
void main() {
writeln("passing lvalue ...");
S s;
fun(s);
writeln("copying struct ...");
auto x = s;
writeln("passing rvalue ...");
fun(S());
writeln("done");
}
As you can see, no postblit is called when the struct is passed
by value:
passing lvalue ...
fun: &x = 7ffffa8c73b8
copying struct ...
postblit 7ffffa8c73b9
passing rvalue ...
fun: &x = 7ffffa8c7370
destructor 7ffffa8c7370
done
destructor 7ffffa8c73b9
destructor 7ffffa8c73b8