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

Reply via email to