Static introspection in a class hierarchy

Rene Zwanenburg via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon May 2 04:12:56 PDT 2016


I'm in the process of making my code compile with DMD 2.071. 
There's a construction I've been using which now results in a 
deprecation message, and I'm not sure how to properly fix it.

It's a bit like design by introspection within a class hierarchy. 
For example:

abstract class Base
{
   private void initialize(){}
}

class Derived : Base
{
   private void initialize(){}
}

Then an external function walks the inheritance chain of a 
statically known derived type and call the init functions. 
Something like this:

void callInitialize(T)(T instance)
{
   static if(BaseClassesTuple!T.length > 1)
   {
     callInitialize!(BaseClassesTuple!T[0])(instance);
   }

   static if(only(__traits(derivedMembers, 
T)).canFind("initialize"))
   {
     auto initializePtr = &__traits(getMember, instance, 
"initialize")
     initializePtr();
   }
}

That __traits(getMember, ... trick was used to access private 
initialize() functions but now results in a deprecation warning:
Deprecation: Derived.initialize is not visible from module 
moduleWhereCallInitializeIsDefined

Declaring both initialize functions as public final doesn't work 
at all:
Error: function Derived.initialize cannot override final function 
Base.initialize

I thought shadowing like this was allowed? Apparently not..

Anyway, what would be the right way to do something like this? I 
don't want to use virtual functions; the need to call 
Base.initialize() in Derived.initialize is leaking implementation 
details and error prone, and I can't afford the overhead. 
(Initialize is a bad example regarding overhead, but I use the 
same mechanism to register callbacks if present. Using static 
introspection makes the difference between thousands of static 
calls that do actual work and millions of useless virtual calls, 
every second)


More information about the Digitalmars-d-learn mailing list