Inheriting constructors

Sean Kelly sean at f4.ca
Fri Jun 1 09:52:30 PDT 2007


Until recently I have been against the idea of inheriting constructors, 
but I've changed my mind.  Inheriting constructors would allow for an 
entire class of generic programming that simply isn't possible right 
now.  The basic rule would be simple and much like the function lookup 
rules already in place: if a class contains no constructors then it 
inherits the constructors of the nearest parent where some are defined. 
  Defining even a single constructor, however, effectively occludes 
superclass constructors and disables this behavior (the workaround being 
an alias, like with function lookup, except that it's currently 
impossible to explicitly reference a class constructor).

The original motivation for this idea was a need for some way to attach 
"on destruct" behavior to an arbitrary class:

     class PrintOnDestruct( T ) :
         public T
     {
         ~this()
         {
             printf( "dtor: %.*s\n", super.classinfo.name );
         }
     }

     class MyClass
     {
         this( int a, int b, int c ) {}
     }

     auto c = new PrintOnDestruct!(MyClass)( a, b, c );

As far as I know, the only way this is currently possible is to 
explicitly write all relevant constructors in PrintOnDestruct.

I believe this feature may also obviate the need for language support of 
placement new:

     class Placed( T ) :
         public T
     {
         new( void* p, size_t sz )
         {
             return p;
         }
     }

     class MyClass
     {
         this( int x ) { val = x; }
         private int val;
     }

     auto p = new(loc) Placed!(MyClass)( 0 );

I can think of other examples as well, but these are the two most 
relevant to what prompted this post in the first place.


On a semi-related note, it would also be nice if there were some way to 
obtain the ParameterTypeTuple for class constructors in general.  Since 
there is currently no way to explicitly reference constructors, this 
sort of thing isn't possible:

     class MyClass
     {
         this( int x ) {}
     }

     alias ParametersOf!(MyClass.this) CtorParams;

The most obvious use case here would be object factories.  Let's say I 
want to be able to generate objects with the same set of parameters each 
time:

     struct TupleInst( Types... )
     {
         Tuple!(Types) data;
     }

     class Factory!( T )
     {
         this( ParametersOf!(T.this) args )
         {
             foreach( i, arg; args )
             {
                 store.data[i] = arg;
             }
         }

         T generate()
         {
             return new T( store.data );
         }

         private TupleInst!(ParametersOf!(T.this)) store;
     }

     class MyClass
     {
         this( int x ) {}
     }

     auto fact = new Factory!(MyClass)( 0 );
     auto objA = fact.generate();
     auto objB = fact.generate();

So something roughly like parameter binding but for constructors.  This 
latter idea likely has less utility than constructor inheritance, but 
I've run into one or two places where it would have been very useful, 
and I had to hack a solution.  Both were essentially similar to the 
example above, but with a different goal in mind.


Sean



More information about the Digitalmars-d mailing list