Jump to page: 1 2
Thread overview
inheriting ctors?
Aug 05, 2010
dcoder
Aug 05, 2010
Sean Kelly
Aug 06, 2010
Rory Mcguire
Aug 06, 2010
Philippe Sigaud
Aug 06, 2010
bearophile
Aug 06, 2010
Philippe Sigaud
Aug 06, 2010
Rory Mcguire
Aug 06, 2010
Rory Mcguire
Aug 05, 2010
Simen kjaeraas
Aug 06, 2010
Rory Mcguire
Aug 06, 2010
Philippe Sigaud
Aug 09, 2010
Rory Mcguire
August 05, 2010
Suppose I have a base class with many ctors().

I want to inherit from the base class and make one slight alteration to it, but I don't want to write X times the following:

this(args) {
  super(args);
}

Does D have an easy way for the derived class to 'inherit' all or some of the
base class ctors(), and just override/add ctors() in the derived class?

In Java, we can use eclipse to auto-generate code for us.  :)  But, the results look cluttered, and it's really not a solution.

Anyways, just curious.

thanks.
August 05, 2010
On Thu, 05 Aug 2010 13:53:20 -0400, dcoder <dcoder@devnull.com> wrote:

> Suppose I have a base class with many ctors().
>
> I want to inherit from the base class and make one slight alteration to it,
> but I don't want to write X times the following:
>
> this(args) {
>   super(args);
> }
>
> Does D have an easy way for the derived class to 'inherit' all or some of the
> base class ctors(), and just override/add ctors() in the derived class?

Sadly, no.  It's been discussed in the past.  I was surprised there were no enhancement requests for it in bugzilla, care to add one?

You may be able to do it with templated constructors, but documentation would suck...

-Steve
August 05, 2010
dcoder <dcoder@devnull.com> wrote:

> Suppose I have a base class with many ctors().
>
> I want to inherit from the base class and make one slight alteration to it,
> but I don't want to write X times the following:
>
> this(args) {
>   super(args);
> }
>
> Does D have an easy way for the derived class to 'inherit' all or some of the
> base class ctors(), and just override/add ctors() in the derived class?

No easy way, no. The best solution might be template or string mixins.

-- 
Simen
August 05, 2010
Steven Schveighoffer Wrote:

> On Thu, 05 Aug 2010 13:53:20 -0400, dcoder <dcoder@devnull.com> wrote:
> 
> > Suppose I have a base class with many ctors().
> >
> > I want to inherit from the base class and make one slight alteration to
> > it,
> > but I don't want to write X times the following:
> >
> > this(args) {
> >   super(args);
> > }
> >
> > Does D have an easy way for the derived class to 'inherit' all or some
> > of the
> > base class ctors(), and just override/add ctors() in the derived class?
> 
> Sadly, no.  It's been discussed in the past.  I was surprised there were no enhancement requests for it in bugzilla, care to add one?

If it helps, I wrote up something on this a few years back:

http://www.digitalmars.com/d/archives/digitalmars/D/Inheriting_constructors_54088.html

Might be a good starting point for an enhancement request.
August 06, 2010
Sean Kelly wrote:

> Steven Schveighoffer Wrote:
> 
>> On Thu, 05 Aug 2010 13:53:20 -0400, dcoder <dcoder@devnull.com> wrote:
>> 
>> > Suppose I have a base class with many ctors().
>> >
>> > I want to inherit from the base class and make one slight alteration to
>> > it,
>> > but I don't want to write X times the following:
>> >
>> > this(args) {
>> >   super(args);
>> > }
>> >
>> > Does D have an easy way for the derived class to 'inherit' all or some
>> > of the
>> > base class ctors(), and just override/add ctors() in the derived class?
>> 
>> Sadly, no.  It's been discussed in the past.  I was surprised there were no enhancement requests for it in bugzilla, care to add one?
> 
> If it helps, I wrote up something on this a few years back:
> 
> 
http://www.digitalmars.com/d/archives/digitalmars/D/Inheriting_constructors_54088.html
> 
> Might be a good starting point for an enhancement request.


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.

Using getOverloads, one should be able to generate or select any of super's constructors. No need for enhancement, just a bug fix. see below:

import std.traits;
import std.conv;


class A {
    int i;
    this(int x) {
        i = x;
    }
    this(float x) {
        i = cast(int)x; // ignore bad code
    }
    this(string s) {
        i = to!int(s);
    }
}
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 ()
constructors.d(34): Error: expected 1 function arguments, not 0
this()
constructors.d(34): Error: constructor constructors.A.this (float x) is not
callable using argument types ()
constructors.d(34): Error: expected 1 function arguments, not 0
this()
constructors.d(34): Error: constructor constructors.A.this (string s) is not
callable using argument types ()
constructors.d(34): Error: expected 1 function arguments, not 0
this()



August 06, 2010
On Fri, Aug 6, 2010 at 11:43, Rory Mcguire <rjmcguire@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


August 06, 2010
Philippe Sigaud:
> This is my new once-a-day bug :(

Add them all to Bugzilla :-)

Bye,
bearophile
August 06, 2010
On Fri, Aug 6, 2010 at 19:09, bearophile <bearophileHUGS@lycos.com> wrote:

> Philippe Sigaud:
> > This is my new once-a-day bug :(
>
> Add them all to Bugzilla :-)
>

I do, from time to time. But I'm never sure if it's a bug or not.

It's related to The Great And Neverending Property Debate (tm). So I don't
what to believe.


Philippe


August 06, 2010
Philippe Sigaud wrote:

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





August 06, 2010
Rory Mcguire wrote:

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

« First   ‹ Prev
1 2