digitalmars.D.learn - Method overloading without Type2Type
- Benjamin Thaut (41/41) Apr 25 2011 I'm just reading Andreis book "Modern C++ Design" and try to translate a...
- bearophile (4/39) Apr 26 2011 Try to compile that code with "-w" (warnings).
- bearophile (3/4) Apr 26 2011 http://d.puremagic.com/issues/show_bug.cgi?id=3836
- Benjamin Thaut (9/13) Apr 26 2011 Thanks, but that is not connected to my question at all,
- Philippe Sigaud (47/52) Apr 26 2011 I'm not sure I understand what you're trying to do (didn't read
- Benjamin Thaut (15/47) Apr 26 2011 The Problem with that version is, that the code that is generated looks ...
- Philippe Sigaud (33/44) Apr 26 2011 ike
- Benjamin Thaut (44/84) Apr 26 2011 struct Foo {...}
- bearophile (9/11) Apr 26 2011 Almost. Maybe to allow addressability with pointers the minimal struct s...
I'm just reading Andreis book "Modern C++ Design" and try to translate a few examples to D 2. My most recent test looks as follows: import std.stdio; struct Type2Type(T){ typedef T OriginalType; } class foo(T,R...) : foo!(R) { public void print(){ super.print(); writefln(T.stringof); } alias foo!(R).echo echo; public void echo(Type2Type!(T)) { writefln(T.stringof); } } class foo(T){ public void print(){ writefln("end " ~ T.stringof); } public void echo(Type2Type!(T)) { writefln(T.stringof); } } void main(string[] args){ auto test = new foo!(int,float,double,short,byte)(); test.print(); test.echo(Type2Type!(double)()); test.echo(Type2Type!(short)()); } I'm wondering if there is any way in D 2 to not use Type2Type so that the calls to echo would look like: test.echo!(double)(); test.echo!(short)(); The solution does not have to use inheritance, any idea? -- Kind Regards Benjamin Thaut
Apr 25 2011
Benjamin Thaut:import std.stdio; struct Type2Type(T){ typedef T OriginalType; } class foo(T,R...) : foo!(R) { public void print(){ super.print(); writefln(T.stringof); } alias foo!(R).echo echo; public void echo(Type2Type!(T)) { writefln(T.stringof); } } class foo(T){ public void print(){ writefln("end " ~ T.stringof); } public void echo(Type2Type!(T)) { writefln(T.stringof); } } void main(string[] args){ auto test = new foo!(int,float,double,short,byte)(); test.print(); test.echo(Type2Type!(double)()); test.echo(Type2Type!(short)()); }Try to compile that code with "-w" (warnings). Bye, bearophile
Apr 26 2011
Try to compile that code with "-w" (warnings).http://d.puremagic.com/issues/show_bug.cgi?id=3836 Bye, bearophile
Apr 26 2011
Am 26.04.2011 13:43, schrieb bearophile:Thanks, but that is not connected to my question at all, I want to implement the echo method so that the type is passed as a template argument, and not as a function argument. While that is happening I still want to be able to overload the function. Is this possible in D 2? -- Kind Regards Benjamin ThautTry to compile that code with "-w" (warnings).http://d.puremagic.com/issues/show_bug.cgi?id=3836 Bye, bearophile
Apr 26 2011
On Tue, Apr 26, 2011 at 18:41, Benjamin Thaut <code benjamin-thaut.de> wrote:Thanks, but that is not connected to my question at all, I want to implement the echo method so that the type is passed as a template argument, and not as a function argument. While that is happening I still want to be able to overload the function. Is this possible in D 2?I'm not sure I understand what you're trying to do (didn't read "Modern C++ design"). Here is something that compiles: import std.stdio; class Foo(T,R...) : Foo!(R) { public void print(){ writeln(T.stringof); super.print(); } public void echo(U)(U u = U.init) { writeln(U.stringof); } } class Foo(T){ public void print(){ writeln("end: " ~ T.stringof); } public void echo(U)(U u = U.init) { writeln(U.stringof); } } void main(string[] args){ auto test = new Foo!(int,float,double,short,byte)(); test.print(); test.echo!double; test.echo!short; } I don't know if classes are necessary for what you've in mind. I tend to use structs: import std.stdio; struct Foo(T,R...) { void print(){ static if (R.length) { Foo!(R) fr; fr.print; } writeln(T.stringof); } void echo(U)(U u = U.init) { writefln(U.stringof);} } void main(string[] args){ Foo!(int,float,double,short,byte) test; test.print; test.echo!double; test.echo!short; }
Apr 26 2011
Am 26.04.2011 21:55, schrieb Philippe Sigaud:On Tue, Apr 26, 2011 at 18:41, Benjamin Thaut<code benjamin-thaut.de> wrote:The Problem with that version is, that the code that is generated looks like void main(string[] args){ auto test = new Foo!(int,float,double,short,byte)(); test.print(); test.echo!double(double.init); test.echo!short(short.init); } If the types that are used, are no simple data types, but rather large structs, they are copied on every function call. Thats exactly what I want to avoid. The Type2Type template has a size of 0, thats why I'm using that in the first place. -- Kind Regards Benjamin ThautThanks, but that is not connected to my question at all, I want to implement the echo method so that the type is passed as a template argument, and not as a function argument. While that is happening I still want to be able to overload the function. Is this possible in D 2?I'm not sure I understand what you're trying to do (didn't read "Modern C++ design"). Here is something that compiles: import std.stdio; class Foo(T,R...) : Foo!(R) { public void print(){ writeln(T.stringof); super.print(); } public void echo(U)(U u = U.init) { writeln(U.stringof); } } class Foo(T){ public void print(){ writeln("end: " ~ T.stringof); } public void echo(U)(U u = U.init) { writeln(U.stringof); } } void main(string[] args){ auto test = new Foo!(int,float,double,short,byte)(); test.print(); test.echo!double; test.echo!short; }
Apr 26 2011
On Tue, Apr 26, 2011 at 22:06, Benjamin Thaut <code benjamin-thaut.de> wrot= e:The Problem with that version is, that the code that is generated looks l=ikevoid main(string[] args){ =C2=A0 =C2=A0 =C2=A0 =C2=A0 auto test =3D new Foo!(int,float,double,short=,byte)();=C2=A0 =C2=A0 =C2=A0 =C2=A0 test.print(); =C2=A0 =C2=A0 =C2=A0 =C2=A0 test.echo!double(double.init); =C2=A0 =C2=A0 =C2=A0 =C2=A0test.echo!short(short.init); } If the types that are used, are no simple data types, but rather large structs, they are copied on every function call. Thats exactly what I wan=tto avoid. The Type2Type template has a size of 0, thats why I'm using tha=tin the first place.In that case, just use echo(U)() { ...}, like this: import std.stdio; class Foo(T,R...) : Foo!(R) { public void print(){ writefln(T.stringof); super.print(); } public void echo(U)() { writefln(U.stringof); } } class Foo(T){ public void print(){ writefln("end: " ~ T.stringof); } public void echo(U)() { writefln(U.stringof); } } void main(string[] args){ auto test =3D new Foo!(int,float,double,short,byte)(); test.print(); test.echo!double; test.echo!short; } What's your global goal with this construction? What are you trying to achi= eve?
Apr 26 2011
Am 26.04.2011 22:41, schrieb Philippe Sigaud:On Tue, Apr 26, 2011 at 22:06, Benjamin Thaut<code benjamin-thaut.de> wrote:struct Foo {...} struct Bar {...} void* poolAllocate(size_t sz){...}; abstract class Allocator(T){ //needs to be implemented by user to fill obj with data public abstract void init(ref T obj); public void make(Type2Type!(T)){ void* ptr = poolAllocate(T.sizeof); T* obj = emplace!(T)(ptr[0..T.sizeof]); init(*obj); } abstract void produce(); } abstract class Allocator(T,R...) : Allocator!(R) { //needs to be implemented by user to fill obj with data public abstract void init(ref T obj); alias Allocator!(R).make make; public void make(Type2Type!(T)){ void* ptr = poolAllocate(T.sizeof); T* obj = emplace!(T)(ptr[0..T.sizeof]); init(*obj); } } class UserImpl : Allocator!(Foo,Bar){ override void init(ref Foo obj){ //fill Foo with data } override void init(ref Bar obj){ //fill Bar with data } override void produce(){ for(...){ make(Type2Type!(Foo)); } for(...){ make(Type2Type!(Bar)); } } } I do this to hide away allocation and pointer arithmetic from the user. -- Kind Regards Benjamin ThautThe Problem with that version is, that the code that is generated looks like void main(string[] args){ auto test = new Foo!(int,float,double,short,byte)(); test.print(); test.echo!double(double.init); test.echo!short(short.init); } If the types that are used, are no simple data types, but rather large structs, they are copied on every function call. Thats exactly what I want to avoid. The Type2Type template has a size of 0, thats why I'm using that in the first place.In that case, just use echo(U)() { ...}, like this: import std.stdio; class Foo(T,R...) : Foo!(R) { public void print(){ writefln(T.stringof); super.print(); } public void echo(U)() { writefln(U.stringof); } } class Foo(T){ public void print(){ writefln("end: " ~ T.stringof); } public void echo(U)() { writefln(U.stringof); } } void main(string[] args){ auto test = new Foo!(int,float,double,short,byte)(); test.print(); test.echo!double; test.echo!short; } What's your global goal with this construction? What are you trying to achieve?
Apr 26 2011
Benjamin Thaut:The Type2Type template has a size of 0, thats why I'm using that in the first place.Almost. Maybe to allow addressability with pointers the minimal struct size in D is 1 byte (0-length fixed-sized arrays may require zero bytes on DMD and 1 bit on LDC): struct Type2Type(T){ typedef T OriginalType; } static assert ((Type2Type!int).sizeof == 1); void main() {} Bye, bearophile
Apr 26 2011