Disabling opAssign in a type disabled all the opAssigns of an aliased type?

aliak something at something.com
Thu Aug 2 14:21:13 UTC 2018


On Tuesday, 31 July 2018 at 07:01:33 UTC, Simen Kjærås wrote:
> On Monday, 30 July 2018 at 23:41:09 UTC, aliak wrote:
>> https://issues.dlang.org/show_bug.cgi?id=19130
>
> Beautiful. :)
>
>> Would it take much to fix it up to use with templated 
>> opAssigns as well?
>
> I spent half an hour doing silly things, then I came up with 
> this:
>
> struct A {
>     void opAssign(int) {}
>     void opAssign(float) {}
>     void opAssign(T)(T t) if (is(T == string)) {}
> }
> struct B {
>     A a;
>     alias a this;
>     @disable void opAssign(float);
>     mixin(wrap!(B, "opAssign"));
>     auto opAssign(T...)(T args)
>     if (__traits(compiles, a.opAssign(args)))
>     {
>         // Look ma, no magic!
>         return a.opAssign(args);
>     }
> }
> unittest {
>     B b;
>     b = "Foo!";
> }
>
> (Remaining code as in my last post)
>
> Yeah, it really is that simple, since specific overloads are 
> tried before templates.
>
> --
>   Simen

Oh nice! So you don't even need all that mixin magic and can get 
away with:

struct A {
     void opAssign(int) {}
     @disable void opAssign(float) {}
     void opAssign(T)(T t) if (is(T == string)) {}
}

struct B(T) {
     A a;
     alias a this;
     @disable void opAssign(B!T);
     mixin(wrap!(B, "opAssign"));
}

string wrap(T, string methodName)() {
     enum targetName = __traits(getAliasThis, T)[0];
     return `auto `~methodName~`(T...)(T args)
         if (__traits(compiles, 
`~targetName~`.`~methodName~`(args))) {
         return `~targetName~`.`~methodName~`(args);
     }`;
}

void main() {
     B!int b;
     b = 3;
     b = "hello";
     static assert(!__traits(compiles, { b = 3f; } ));
     static assert(!__traits(compiles, { b = b; } ));
}






More information about the Digitalmars-d-learn mailing list