Move construction from !is(T == typeof(this))
Manu via Digitalmars-d
digitalmars-d at puremagic.com
Tue Apr 25 19:19:03 PDT 2017
On 25 April 2017 at 14:17, Stanislav Blinov via Digitalmars-d <
digitalmars-d at puremagic.com> wrote:
> 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.
>
Right, yeah I see. So, basically, you admit that it is required to have 3
overloads; foo(X), foo(ref X) and foo(ref const X), in the event that I
want to avoid needlessly copying X prior to constructing from it in the
non-const case...
I can imagine in some cases, copy constructing from X, and making a copy of
X then move constructing from X are similar/same cost... so it's really
just a gotcha that authors need to be aware of.
I feel this is complicated and there are a lot of particulars. This needs
to be documented clearly in the language docs, and there should probably be
some examples how it relates to C++'s copy/move construction offerings,
because it's significantly different and anyone with C++ experience will
fail to get this right.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20170426/95859c35/attachment.html>
More information about the Digitalmars-d
mailing list