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