meaning of "auto ref const"?

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Dec 20 12:08:32 PST 2016


On 12/18/2016 05:14 AM, Picaud Vincent wrote:

 > Another interrogation for me, who come from C++, is how to translate
 > into D:
 >
 > template<typename T> void foo(T&& t);

If it means "rvalue reference"[1], then there is no equivalent is D 
because D does not allow references to rvalues, even if const.

If the purpose is optimization, the good news are

* Classes are already reference types so there is no lvalue or rvalue 
reference distinction there

* rvalue structs are automatically moved to functions when passed by-copy

import std.stdio;

struct S {
     double i;
     ubyte[1000] buf;
     this(int i) {
         this.i = i;
         writefln("constructor       %s", i);
     }
     this(this) {
         writef(  "post-blit         %s -> ", i);
         this.i += 0.1;
         this.buf = buf.dup;
         writeln(i);
     }
     ~this() {
         writefln("destructor for    %s", i);
     }
}

void foo(S s) {
     writefln(    "foo(by-copy)      %s", s.i);
}

void foo(ref const(S) s) {
     writefln(    "foo(by-ref-const) %s", s.i);
}

// UNCOMMENT THIS TO BE SURPRISED:
// void foo(ref S s) {
//     writefln(    "foo(by-ref)       %s", s.i);
// }

void main() {
     {
         writeln("\n--- rvalue ---");
         foo(S(1));
     }
     {
         writeln("\n--- mutable lvalue ---");
         auto s = S(2);
         foo(s);
     }
     {
         writeln("\n--- const lvalue ---");
         const s = S(3);
         foo(s);
     }
}

According to the output, there is no post-blit executed for the rvalue:

--- rvalue ---
constructor       1
foo(by-copy)      1
destructor for    1

--- mutable lvalue ---
constructor       2
post-blit         2 -> 2.1
foo(by-copy)      2.1
destructor for    2.1
destructor for    2

--- const lvalue ---
constructor       3
foo(by-ref-const) 3
destructor for    3

There is a surprising difference in D:

* First, in C++, you cannot have both the by-copy and by-ref-to-const 
overload of a function: It would be ambiguous for rvalues.

* You can have that in D, which brings the interesting difference:

In D, non-constness of an object seems to be more important in overload 
resolution: Notice how mutable lvalue above is passed to by-copy instead 
of the potentially-more-optimal by-const-ref above. D realizes that a 
mutable object is for mutation and because by-const-ref cannot mutate 
it, D passes it to the by-copy function. (This may be seen as a bug by 
some.)

Interestingly, enabling the by-mutable-ref overload above, now the 
mutable object goes to by-ref and there is no automatic copy:

--- rvalue ---
constructor       1
foo(by-copy)      1
destructor for    1

--- mutable lvalue ---
constructor       2
foo(by-ref)       2
destructor for    2

--- const lvalue ---
constructor       3
foo(by-ref-const) 3
destructor for    3

Ali

[1] I have an issue with "rvalue reference" as rvalue references can be 
references to lvalues as well. :p



More information about the Digitalmars-d-learn mailing list