digitalmars.D.learn - inheriting ctors?
- dcoder (12/12) Aug 05 2010 Suppose I have a base class with many ctors().
- Steven Schveighoffer (6/16) Aug 05 2010 Sadly, no. It's been discussed in the past. I was surprised there were...
- Sean Kelly (4/22) Aug 05 2010 If it helps, I wrote up something on this a few years back:
- Rory Mcguire (38/64) Aug 06 2010 I've been trying to make a template for this but it seems that dmd still...
- Philippe Sigaud (21/32) Aug 06 2010 This is my new once-a-day bug :(
- bearophile (4/5) Aug 06 2010 Add them all to Bugzilla :-)
- Philippe Sigaud (5/8) Aug 06 2010 I do, from time to time. But I'm never sure if it's a bug or not.
- Rory Mcguire (39/86) Aug 06 2010 Thanks!! works now. Now we just need to be able to select which construc...
- Rory Mcguire (31/124) Aug 06 2010 Got selection working:
- Simen kjaeraas (4/14) Aug 05 2010 No easy way, no. The best solution might be template or string mixins.
- Rory Mcguire (3/22) Aug 06 2010 Here is a possible solution to your problem:
- Philippe Sigaud (45/47) Aug 06 2010 I believe you can get the type of A. Isn't it typeof(super) or
- Rory Mcguire (6/75) Aug 09 2010 I'll see what I can do to shorten it but I'm not sure how to iterate ove...
- Andrej Mitrovic (6/138) Aug 06 2010 There is an AutoImplement class template in http://www.digitalmars.com/d...
- Andrej Mitrovic (36/180) Aug 06 2010 Here's an example:
- Rory Mcguire (5/6) Aug 09 2010 I had been trying to use AutoImplement to make something before but it g...
- Rory Mcguire (3/4) Aug 09 2010 [snip]
- div0 (8/11) Aug 07 2010 lol, that's true. I've been basing out c++ & d template code for years
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
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
Steven Schveighoffer Wrote:On Thu, 05 Aug 2010 13:53:20 -0400, dcoder <dcoder devnull.com> wrote: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.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?
Aug 05 2010
Sean Kelly wrote:Steven Schveighoffer Wrote:http://www.digitalmars.com/d/archives/digitalmars/D/Inheriting_constructors_54088.htmlOn Thu, 05 Aug 2010 13:53:20 -0400, dcoder <dcoder devnull.com> wrote:If it helps, I wrote up something on this a few years back: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?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
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
Philippe Sigaud:This is my new once-a-day bug :(Add them all to Bugzilla :-) Bye, bearophile
Aug 06 2010
On Fri, Aug 6, 2010 at 19:09, bearophile <bearophileHUGS lycos.com> wrote:Philippe Sigaud: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. PhilippeThis is my new once-a-day bug :(Add them all to Bugzilla :-)
Aug 06 2010
Philippe Sigaud wrote:On Fri, Aug 6, 2010 at 11:43, Rory Mcguire <rjmcguire gm_no_ail.com> wrote: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); }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
Rory Mcguire wrote:Philippe Sigaud wrote: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)))()); }On Fri, Aug 6, 2010 at 11:43, Rory Mcguire <rjmcguire gm_no_ail.com> wrote: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); }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
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
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
On Fri, Aug 6, 2010 at 21:59, Rory Mcguire <rjmcguire gm_no_ail.com> wrote:Here is a possible solution to your problem: -RoryI 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
Philippe Sigaud wrote:On Fri, Aug 6, 2010 at 21:59, Rory Mcguire <rjmcguire gm_no_ail.com> wrote: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)"Here is a possible solution to your problem: -RoryI 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 09 2010
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: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)))()); }On Fri, Aug 6, 2010 at 11:43, Rory Mcguire <rjmcguire gm_no_ail.com> wrote: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); }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
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: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)))()); }On Fri, Aug 6, 2010 at 11:43, Rory Mcguire <rjmcguire gm_no_ail.com> wrote: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); }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
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
Thanks for suggestion Andrej Mitrovic wrote:Here's an example:[snip]
Aug 09 2010
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