www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - passing subclass to superclass where parameter is a delegate for the

reply Chris Bare <chris bareflix.com> writes:
If I have:
class base
{
     void delegate(base) stored_dg;

     void
     add_function (void delegate (base) dlg)
     {
         stored_dg = dlg;
     }
}

class A : base
{
     this ()
     {
         super ();
         add_function (&this.foo);
     }

     void foo (A a)
     {
         log ("i got here");
     }
}

it fails because foo(A) does not match the parameter type of 
delegate(base)

If I change foo (A a) to foo (base a)

It works, but this could be awkward in a deeper class hierarchy 
where you
might not know the class name to use.

Is there a way to do this where foo's parameter type does not to 
match the
class that implements add_function?

Thanks,
Chris
Nov 14 2018
parent reply Alex <sascha.orlov gmail.com> writes:
On Wednesday, 14 November 2018 at 16:06:21 UTC, Chris Bare wrote:
 If I have:
 class base
 {
     void delegate(base) stored_dg;

     void
     add_function (void delegate (base) dlg)
     {
         stored_dg = dlg;
     }
 }

 class A : base
 {
     this ()
     {
         super ();
         add_function (&this.foo);
     }

     void foo (A a)
     {
         log ("i got here");
     }
 }

 it fails because foo(A) does not match the parameter type of 
 delegate(base)

 If I change foo (A a) to foo (base a)

 It works, but this could be awkward in a deeper class hierarchy 
 where you
 might not know the class name to use.

 Is there a way to do this where foo's parameter type does not 
 to match the
 class that implements add_function?

 Thanks,
 Chris
Are you looking for this? https://dlang.org/phobos/std_traits.html#TransitiveBaseTypeTuple It matches however not exactly your needs: As all objects are derived from the Object class, you will always get it as the common parent. So... with the trait, you get a list but have still to make a decision which type to use.
Nov 14 2018
parent Alex <sascha.orlov gmail.com> writes:
On Wednesday, 14 November 2018 at 16:39:52 UTC, Alex wrote:
 Are you looking for this?
 https://dlang.org/phobos/std_traits.html#TransitiveBaseTypeTuple

 It matches however not exactly your needs:
 As all objects are derived from the Object class, you will 
 always get it as the common parent. So... with the trait, you 
 get a list but have still to make a decision which type to use.
Maybe, something like this: ´´´ import std.traits; template properBase(T) { static foreach(i, t; TransitiveBaseTypeTuple!A) { static if(hasMember!(t, "add_function")){} else { static if(!__traits(compiles, {auto c = properBase.init;})) { alias properBase = TransitiveBaseTypeTuple!A[i-1]; } } } } void main(){} class base { void delegate(typeof(this)) stored_dg; this(){} void add_function (void delegate (typeof(this)) dlg) { stored_dg = dlg; } } class A : base { alias pB = properBase!A; this () { super (); add_function (&this.foo); } void foo (pB a) { import std.experimental.logger; log ("i got here"); } } ´´´
Nov 14 2018