There is an AutoImplement class template in 
http://www.digitalmars.com/d/2.0/phobos/std_typecons.html#AutoImplement , which 
I've just been trying out. Apparently you can pass it 1: a Base class, 2: a 
templated function to filter out which functions you want to inherit/overwrite 
from the Base class, and 3: a template function which can re-write the bodies 
of each function which is not filtered out (+ there are some "macros" which you 
can use to quickly access the functions' parameters and other such things).

But it's a mess to work with, and I'm not sure how I'm supossed to use it if 
I'm trying to do something like "class B : A".., because it looks like 
AutoImplement creates a class and instantiates it, it doesn't return a string 
ready to be mixed in like you are doing in your example.

There's an example of BlackBox and WhiteBox, which use AutoImplement, on the 
same page. Maybe you guys could make sense of it, it's too hard for me atm. (D 
newbie)

// Offtopic
Template errors are so hard to grasp, most of the time it's best to just ignore 
them and take some logical steps to fix the errors. At least that's in my case 
true..

Rory Mcguire Wrote:

> Rory Mcguire wrote:
> 
> > Philippe Sigaud wrote:
> > 
> >> On Fri, Aug 6, 2010 at 11:43, Rory Mcguire <rjmcgu...@gm_no_ail.com>
> >> wrote:
> >> 
> >> 
> >>> I've been trying to make a template for this but it seems that dmd still
> >>> won't allow me to get the parameters of the constructors. dmd Seems to
> >>> think
> >>> that I'm trying to use it as a property.
> >>>
> >>>
> >> 
> >>> void main() {
> >>>    foreach (m; __traits(getOverloads, A, "__ctor")) {
> >>>        pragma(msg, m.stringof); // it thinks I'm calling m
> >>>    }
> >>> }
> >>>
> >>> constructors.d(34): Error: constructor constructors.A.this (int x) is
> >>> not callable using argument types ()
> >>>
> >> 
> >> This is my new once-a-day bug :(
> >> Using a function alias, and being unable to call properties on it,
> >> because DMD thinks I'm calling it. Man, it's no property, just a name!
> >> 
> >> Anyway, just pragma(msg, m) works, strangely.
> >> I think I found a way to use m, somewhat:
> >> 
> >> void main() {
> >>    foreach (m; __traits(getOverloads, A, "__ctor")) {
> >>        pragma(msg, m); // it thinks I'm calling m
> >>        typeof(&m) tmp = &m;
> >>         writeln( (ParameterTypeTuple!tmp).stringof); // (int), (double),
> >> (string)
> >>         writeln( (ParameterTypeTuple!m).stringof); // (int), (int), (int)
> >>         writeln( typeof(&m).stringof); // A function(int x), A
> >> function(double x), A function(string s)
> >>    }
> >> }
> >> 
> >> using ParameterTypeTuple!m directly does not differentiate the m's. But
> >> using a temporary pointer, it seems to work.
> >> 
> >> Oh and I even get the arguments names !
> >> 
> >> 
> >> Philippe
> > 
> > Thanks!! works now. Now we just need to be able to select which
> > constructors we actually want.
> > 
> > string inheritconstructors_helper(alias T)() {
> >     string s;
> >     foreach (m; __traits(getOverloads, T, "__ctor")) {
> >         string args, args1;
> >         foreach (i, cons; ParameterTypeTuple!(typeof(&m))) {
> >             pragma(msg, cons.stringof);
> >             args ~= ","~cons.stringof~" v"~to!string(i);
> >             args1 ~= ",v"~to!string(i);
> >         }
> >         args = args.length < 1 ? args : args[1..$];
> >         args1 = args1.length < 1 ? args1 : args1[1..$];
> >         s ~= "this("~args~") { super("~args1~"); }\n";
> >     }
> >     return s;
> > }
> > 
> > class A {
> >     int i;
> >     //private this() {}
> >     this(int x) {
> >         i = x;
> >     }
> >     this(float x) {
> >         i = cast(int)x; // ignore bad code
> >     }
> >     this(string s, int mul) { // test multiple args
> >         i = to!int(s) * mul;
> >     }
> > }
> > class B : A {
> >     mixin(inheritconstructors_helper!A());
> > //  InheritConstructors!A;
> > }
> > 
> > 
> > 
> > void main() {
> >     A a = new B(4);
> >     a = new B("42", 2);
> > }
> 
> Got selection working:
> 
> string inheritconstructors_helper(alias T,Selectors...)() {
>     string s;
>     
>     foreach (m; __traits(getOverloads, T, "__ctor")) {
>         string args, args1;
>         pragma(msg, typeof(&m));
>         /*foreach (sel; Selectors) {
>             pragma(msg, sel, is (sel == typeof(&m)));
>             continue top;
>         }*/
>         if (staticIndexOf!(typeof(&m), Selectors)==-1) {
>             continue;
>         }
>         foreach (i, cons; ParameterTypeTuple!(typeof(&m))) {
>             pragma(msg, cons.stringof);
>             args ~= ","~cons.stringof~" v"~to!string(i);
>             args1 ~= ",v"~to!string(i);
>         }
>         args = args.length < 1 ? args : args[1..$];
>         args1 = args1.length < 1 ? args1 : args1[1..$];
>         s ~= "this("~args~") { super("~args1~"); }\n";
>     }
>     return s;
> }
> 
> 
> 
> Usage:
> 
> class B : A {
>     mixin(inheritconstructors_helper!(A,TypeTuple!(A function(string,int)
>                       ,A function(int)))());
> }
> 

Reply via email to