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

Stanislav Blinov via Digitalmars-d digitalmars-d at puremagic.com
Mon Apr 24 16:13:07 PDT 2017


On Monday, 24 April 2017 at 22:46:18 UTC, Andrei Alexandrescu 
wrote:
> On 04/24/2017 04:23 PM, ag0aep6g wrote:
>> On 04/24/2017 08:48 PM, Stanislav Blinov wrote:
>>> Speaking of const violation and UB, 
>>> std.algorithm.mutation.move seems to
>>> violate const without remorse:
>>
>> Yup. Even in @safe code, which is a bug.
>> https://issues.dlang.org/show_bug.cgi?id=15315
>
> Should fail in all situations, thanks for reporting.

So, basically any type with const/immutable members effectively 
becomes immovable?

> There should be ways to do this easier, i.e. add a forward() 
> function to std.algorithm.mutation. Contributions are welcome!

Ah, thanks for the hint. There actually is one in std.functional, 
but it's not designed to handle one-argument situations well 
(returns a tuple instead of forwarding the argument). This works:

import std.algorithm.mutation : move;

template forward(args...)
{
     import std.meta;

     static if (args.length)
     {
         static if (__traits(isRef, args[0]))
             alias fwd = args[0];
         else
             @property fwd() { return move(args[0]); }

         static if (args.length == 1)
             alias forward = fwd;
         else
             alias forward = AliasSeq!(fwd, forward!(args[1..$]));
     }
     else alias forward = AliasSeq!();
}

struct Y
{
     private X _x;
     this()(auto ref X x)
     {
         _x = forward!x;
     }
}

struct X {
     this(this) { writeln("copy"); }
}

void main()
{
     X x;
     Y y = x;        // outputs "copy"
     Y y2 = move(x); // moves, postblit not called
}

I'll make the PR.


More information about the Digitalmars-d mailing list