On Monday, 29 May 2017 at 08:41:05 UTC, Jonathan M Davis wrote:
I probably didn't say it very well.
With C++, if you have const T&, it will accept both lvalues and
rvalues. A number of folks (particularly those writing games)
want an equivalent to that in D where they can then pass both
lvalues and rvalues without incurring a copy. Historically,
Andrei has been against it because of issues with rvalue
references, but based on some of the more recent discussions,
it sounds like it _might_ be possible to come up with a
solution that he'd be okay with (particularly with some of the
improvements that come with DIPs 25 and 1000). Ethan Watson has
expressed interest in writing a DIP on the matter, so I expect
that we'll see one at some point here.
- Jonathan M Davis
This indeed does sound like a good extension for DIP1000, i.e:
struct Vector3 { float x, y, z; }
void foo(in ref Vector3 v) { /*...*/ }
foo(Vector3(1,2,3));
Invalid now, even with -dip1000, but, since `in` is `const scope`
it feels like it should be made allowed: `scope` guarantees the
reference won't escape, the argument obviously will live through
the call to foo(), so it could be made to "just work", even for
mutables, i.e. `scope ref`. Of course, without `scope` it should
remain an error.
In regards to move semantics and && also mentioned here, there is
only one case where current D looks inferior to C++: D's "double
move":
struct X
{
Y y;
this(Y y) { move(y, this.y); }
}
auto x = X(Y());
// ctor above benefits from the compiler, so here's
// a more explicit case:
Y y;
X x2 = move(y);
With rvalue references and explicit move semantics of C++, this
could be made into one bitblast. With current D, it requires two.
However, this does seem like a compiler optimization issue, and
is mentioned by Andrei:
https://github.com/dlang/phobos/pull/4971#issuecomment-268038627
So all in all, it looks to be possible to achieve the desired
results purely by enhancing the language, with no syntax changes
and without adding any "rvalue reference" types.