template this and traits getOverloads issue.

Alex Parrill via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Nov 20 06:17:58 PST 2015


On Friday, 20 November 2015 at 14:01:13 UTC, BBasile wrote:
> Background:
> ===========
>
> http://stackoverflow.com/questions/33764540/warning-about-overriden-methods-when-using-a-mixin
>
> Why this horrible trick has to be used:
> =======================================
>
> cast this as (T) in a function template that's been mixed in an 
> ancestor is not always usable, unless I miss something:
>
> ----
> import std.stdio;
>
> mixin template Bug()
> {
>     import std.traits;
>     void bug(T)()
>     {
>         foreach(member; __traits(allMembers, T))
>             foreach(overload; __traits(getOverloads, T, member))
>         {
>                 auto dg = &overload;
>                 writeln(member);
>         }
>     }
> }
>
> class A
> {
>     mixin Bug;
>     this(){bug!A;}
>     void foo(){}
> }
>
> class B: A
> {
>     void bar(){}
>     void bar(uint a){}
>     this(){bug!B;}
> }
>
> void main(){
>     new A;
>     new B;
> }
> ----
>
>
>>a.d(11,27): Error: this for bar needs to be type B not type a.A
>>a.d(11,27): Error: this for bar needs to be type B not type a.A
>>a.d(11,27): Error: this for this needs to be type B not type a.A
>
>
> everything that can be done to avoid the compilations errors 
> will also prevent "bar" to be written in the output (because a 
> B will never be analyzed). The "only" fix I see is like in the 
> stack overflow answer: statically check if the mixin methods 
> are already there and remix the mixin in each descendant, so 
> that the getOverloads traits works on the right 'this'.
>
> What do you think ? is it a bug ?

Templates are not virtual, which is why you might be running into 
issues here; bug thinks it's being called on an `A` object.

But you don't need a template for this case; mixin templates have 
access to `this`:

---
import std.stdio;

mixin template Bug()
{
     import std.traits;
     override void bug()
     {
         foreach(member; __traits(allMembers, typeof(this)))
             foreach(overload; __traits(getOverloads, 
typeof(this), member))
         {
                 auto dg = &overload;
                 writeln(member);
         }
     }
}

// Interface to allow for mixin template to use `override` 
without worrying if
// `bug` is the first implementation or not.
interface IF {
     void bug();
}

class A : IF
{
     mixin Bug;
     this(){bug();}
     void foo(){}
}

class B: A
{
     mixin Bug; // need mixin on B now to override `bug` for the 
new class
     void bar(){}
     void bar(uint a){}
}

void main(){
     new A;
     new B;
}


More information about the Digitalmars-d-learn mailing list