Move construction from !is(T == typeof(this))

Stanislav Blinov via Digitalmars-d digitalmars-d at puremagic.com
Mon Apr 24 21:17:48 PDT 2017


On Tuesday, 25 April 2017 at 01:59:55 UTC, Manu wrote:

> Ah crap, I somehow missed the single-argument move() function.
>
> Okay, so this pattern is definitely reliable? I haven't seen it 
> clearly documented anywhere that this is the prescribed 
> pattern, and it's come up on stack overflow a few times, but it 
> hasn't been answered correctly.
> I think this is poorly distributed knowledge.

It is definitely reliable.

> As Schveighoffer pointed out, this pattern requires *another* 
> overload for `ref const X`? Surely if there is no `ref X` and 
> only a `ref const X` available, it should choose that one 
> rather than the byval one when the argument is not const (as 
> demonstrated in the bug report?)

No, the bug report is incorrect. See 
http://dlang.org/spec/function.html#function-overloading. 
Remember that, unlike C++'s '&', "ref" is not a type, it's a 
parameter storage class. So, given the overloads

foo(const ref X);
foo(X x);

or, more precisely:

foo(ref const(X));
foo(X x);

if you call foo with a non-const X lvalue *or* rvalue, the second 
overload will be chosen (the exact match):

X x;
foo(x);   // typeof(x) == X, so foo(X) is chosen. It's passed by 
value, so x is copied first.
foo(X()); // also calls foo(X), this time no copy is needed

const X cx;
foo(cx); // calls foo(ref const(X)), since typeof(cx) == const(X)

In C++, those foos would be ambiguous. In D, they aren't, because 
it first checks whether it's const or not, and then whether it's 
an lvalue or an rvalue.

> It's demonstrated that `ref const X` might inhibit an efficient 
> copy constructor implementation in some cases, but you can't 
> have false-move's occurring when the lvalue is not const.

It's not about efficiency, it's about preserving type 
information. Once you slap "const" on, there's no getting rid of 
it without violating the type system.
And there won't be any "false" moves. You either have a reference 
to copy from, or a full-blown copy/rvalue to move from.


More information about the Digitalmars-d mailing list