inheriting ctors?

Rory Mcguire rjmcguire at gm_no_ail.com
Fri Aug 6 12:23:05 PDT 2010


Rory Mcguire wrote:

> Philippe Sigaud wrote:
> 
>> On Fri, Aug 6, 2010 at 11:43, Rory Mcguire <rjmcguire at 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)))());
}



More information about the Digitalmars-d-learn mailing list