www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - inheriting ctors?

reply dcoder <dcoder devnull.com> writes:
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.
Aug 05 2010
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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
Aug 05 2010
parent reply Sean Kelly <sean invisibleduck.org> writes:
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.
Aug 05 2010
parent reply Rory Mcguire <rjmcguire gm_no_ail.com> writes:
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()
Aug 06 2010
parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
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
Aug 06 2010
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Philippe Sigaud:
 This is my new once-a-day bug :(
Add them all to Bugzilla :-) Bye, bearophile
Aug 06 2010
parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
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
Aug 06 2010
prev sibling parent reply Rory Mcguire <rjmcguire gm_no_ail.com> writes:
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); }
Aug 06 2010
parent Rory Mcguire <rjmcguire gm_no_ail.com> writes:
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)))()); }
Aug 06 2010
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
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
Aug 05 2010
prev sibling next sibling parent reply Rory Mcguire <rjmcguire gm_no_ail.com> writes:
dcoder 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?
 
 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.
Here is a possible solution to your problem: -Rory
Aug 06 2010
parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Fri, Aug 6, 2010 at 21:59, Rory Mcguire <rjmcguire gm_no_ail.com> wrote:

 Here is a possible solution to your problem:

 -Rory
I believe you can get the type of A. Isn't it typeof(super) or std.traits.BaseClassesTuple!B[0] ? B in the latter case being typeof(this) That way, there is no need for the user to provide A, it's automatically found by the template. Warning: I did not test this. And, we know the constructs are of type 'A function(someTypes)' [*], so the 'A function' part is redundant. Hence, the user only needs to provide for the args types and that makes for a cleaner call. * either as a list : mixin(InheritConstructors!(int, double, string)); // I want to inherit the constructors taking one type, build me the __ctors for int, double and string * or, in the case of multi-parameters constructors, wrap them in a tuple: mixin(InheritConstructors!(int, double, Tuple!(int, double)); // I want super(int), super(double) and super(int, double) That means iterating on the type list, and determining if the current type is a tuple or not * if its a 'normal' type, create the corresponding contructor * if it's a Tuple, crack it open and get the types, using the .Types alias std.typecons.Tuples have. Creating a constructor from this typetuple is no different from creating it for one type. To determine if something is a std.typecons.Tuple, you cannot use an is() expression: they do not allow multiple types: enum bool isTuple = is(T == Tuple!U, U...); // no. U... is not allowed. Hmm, enhancement request? So, you can either rely on it having a .Types 'member': template isTuple(T) { enum bool isTuple = is(T.Types); } Pb: that will flag as tuples any type that exposes a ".Types" alias. Or use a function accepting a Tuple: template isTuple(T) { enum bool isTuple = is(typeof({ void foo(U...)(Tuple!U t) {}; // this function accepts only tuples foo(T.init); // test it }())); } It's ugly as a rat's ass, but it's more solid than the former template. Philippe [*] btw, shouldn't that be A delegate(someTypes)???
Aug 06 2010
parent Rory Mcguire <rjmcguire gm_no_ail.com> writes:
Philippe Sigaud wrote:

 On Fri, Aug 6, 2010 at 21:59, Rory Mcguire <rjmcguire gm_no_ail.com>
 wrote:
 
 Here is a possible solution to your problem:

 -Rory
I believe you can get the type of A. Isn't it typeof(super) or std.traits.BaseClassesTuple!B[0] ? B in the latter case being typeof(this) That way, there is no need for the user to provide A, it's automatically found by the template. Warning: I did not test this. And, we know the constructs are of type 'A function(someTypes)' [*], so the 'A function' part is redundant. Hence, the user only needs to provide for the args types and that makes for a cleaner call. * either as a list : mixin(InheritConstructors!(int, double, string)); // I want to inherit the constructors taking one type, build me the __ctors for int, double and string * or, in the case of multi-parameters constructors, wrap them in a tuple: mixin(InheritConstructors!(int, double, Tuple!(int, double)); // I want super(int), super(double) and super(int, double) That means iterating on the type list, and determining if the current type is a tuple or not * if its a 'normal' type, create the corresponding contructor * if it's a Tuple, crack it open and get the types, using the .Types alias std.typecons.Tuples have. Creating a constructor from this typetuple is no different from creating it for one type. To determine if something is a std.typecons.Tuple, you cannot use an is() expression: they do not allow multiple types: enum bool isTuple = is(T == Tuple!U, U...); // no. U... is not allowed. Hmm, enhancement request? So, you can either rely on it having a .Types 'member': template isTuple(T) { enum bool isTuple = is(T.Types); } Pb: that will flag as tuples any type that exposes a ".Types" alias. Or use a function accepting a Tuple: template isTuple(T) { enum bool isTuple = is(typeof({ void foo(U...)(Tuple!U t) {}; // this function accepts only tuples foo(T.init); // test it }())); } It's ugly as a rat's ass, but it's more solid than the former template. Philippe [*] btw, shouldn't that be A delegate(someTypes)???
I'll see what I can do to shorten it but I'm not sure how to iterate over the Selectors inside the foreach and still be able to skip unselected constructors. Hmmm I suppose I could use a temporary boolean or something. I don't use "A delegate(someTuypes)" because the compiler says that the type of the constructors is for instance: "A function(int x)"
Aug 09 2010
prev sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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 <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)))()); }
Aug 06 2010
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Here's an example:

import std.stdio;
import std.traits;
import std.conv;
import std.typecons;

class C
{
    int m_value;
    
    int testMe()
    {
        return 1;
    }
    
    this(int x) 
    { 
        m_value = x; 
    }
    
    this(int x, int z)
    {
        m_value = x + z;
    }
}

template inheritClassMethods(Base)
{
    alias AutoImplement!(Base, generateEmptyFunction, isAbstractFunction)
inheritClassMethods;
}

void main()
{
    auto c = new inheritClassMethods!C(42, 56);
} 

So basically you can instantiate a highly modified class that's based on
another class at compile time. You can change the method definitions, and even
leave some out. What's really cool about this is that you can, say, add logging
ability to all methods of a class without having to manually add them in class
definition (there's an example in the docs). Which could be quite useful in
debugging I suposse.

isAbstractFunction and generateEmptyFunction are from std.typecons (I think),
but you can pass your own template functions instead of these.

I'm just getting a lot of errors because it seems very sensitive to what kind
of functions you're going to inherit.. well it's complicated. And there's some
warnings about bugs in the sources. Still, I like the premise of AutoImplement.

Andrej Mitrovic Wrote:

 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 <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)))()); }
Aug 06 2010
next sibling parent Rory Mcguire <rjmcguire gm_no_ail.com> writes:
I had been trying to use AutoImplement to make something before but it gave 
me weird errors.
I'm going to try using it for implementing "this" when I get some time.

Andrej Mitrovic wrote:

 Here's an example:
[snip]
Aug 09 2010
prev sibling parent Rory Mcguire <rjmcguire gm_no_ail.com> writes:
Thanks for suggestion

Andrej Mitrovic wrote:

 Here's an example:
[snip]
Aug 09 2010
prev sibling parent div0 <div0 sourceforge.net> writes:
On 06/08/2010 22:57, Andrej Mitrovic wrote:

 // 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..
lol, that's true. I've been basing out c++ & d template code for years and that's pretty much what I do. Unless the template author has specifically added static asserts to catch an obvious error, most template error messages are useless garbage. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Aug 07 2010