digitalmars.D - Templated Functions
- Tomás Rossi <Tomás_member pathlink.com> Oct 31 2005
- "John C" <johnch_atms hotmail.com> Oct 31 2005
- Tomás Rossi <Tomás_member pathlink.com> Oct 31 2005
- "John C" <johnch_atms hotmail.com> Oct 31 2005
- Tomás Rossi <Tomás_member pathlink.com> Oct 31 2005
- "John C" <johnch_atms hotmail.com> Oct 31 2005
- Derek Parnell <derek psych.ward> Oct 31 2005
- Tomás Rossi <Tomás_member pathlink.com> Oct 31 2005
- Bruno Medeiros <daiphoenixNO SPAMlycos.com> Nov 01 2005
- Tomás Rossi <Tomás_member pathlink.com> Nov 01 2005
- Oskar Linde <Oskar_member pathlink.com> Nov 01 2005
- Tomás Rossi <Tomás_member pathlink.com> Nov 01 2005
- David Medlock <noone nowhere.com> Nov 01 2005
- Tomás Rossi <Tomás_member pathlink.com> Nov 01 2005
- cpunion gmail.com Nov 04 2005
- "John C" <johnch_atms hotmail.com> Nov 04 2005
- cpunion gmail.com Nov 04 2005
- cpunion gmail.com Nov 04 2005
- "John C" <johnch_atms hotmail.com> Nov 05 2005
- cpunion gmail.com Nov 05 2005
In C++ one could do this:
template <class T>
void genericFunction<T>(someParam1, someParam2, ..., someParamN)
{...generic algorithm...}
and then:
..
genericFunction< list<int> >(blah blah ...);
..
Is this possible in D?
Tom
Oct 31 2005
"Tomás Rossi" <Tomás_member pathlink.com> wrote in message news:dk50a0$mmk$1 digitaldaemon.com...In C++ one could do this: template <class T> void genericFunction<T>(someParam1, someParam2, ..., someParamN) {...generic algorithm...} and then: .. genericFunction< list<int> >(blah blah ...); .. Is this possible in D?
Yes, it's in the documentation http://www.digitalmars.com/d/template.html template genericFunction (T) { void genericFunction(T p1, T p2, ..., T pN) { } } genericFunction!(list!(int))(...);Tom
Oct 31 2005
In article <dk52us$qpb$1 digitaldaemon.com>, John C says..."Tomás Rossi" <Tomás_member pathlink.com> wrote in message news:dk50a0$mmk$1 digitaldaemon.com...In C++ one could do this: template <class T> void genericFunction<T>(someParam1, someParam2, ..., someParamN) {...generic algorithm...} and then: .. genericFunction< list<int> >(blah blah ...); .. Is this possible in D?
Yes, it's in the documentation http://www.digitalmars.com/d/template.html template genericFunction (T) { void genericFunction(T p1, T p2, ..., T pN) { } } genericFunction!(list!(int))(...);Tom
Ok, I read the docs but the syntax was not so clear to me. Anyway, the C++ syntax (not referring about <>) is a lot better in the sense that you are not bound to name your template: /////////////////////////////////////// template genericFunctions(T) { T genericFunction1() {return T.max;} T genericFunction2() {return T.min;} .. } toString( genericFunctions.genericFunction1!(int)() ); toString( genericFunctions.genericFunction2!(int)() ); .. /////////////////////////////////////// It just looks ugly! What about having some kind of anonymous template. (Please correct me if i'm wrong) Tom
Oct 31 2005
"Tomás Rossi" <Tomás_member pathlink.com> wrote in message news:dk5lqe$1gar$1 digitaldaemon.com...In article <dk52us$qpb$1 digitaldaemon.com>, John C says..."Tomás Rossi" <Tomás_member pathlink.com> wrote in message news:dk50a0$mmk$1 digitaldaemon.com...In C++ one could do this: template <class T> void genericFunction<T>(someParam1, someParam2, ..., someParamN) {...generic algorithm...} and then: .. genericFunction< list<int> >(blah blah ...); .. Is this possible in D?
Yes, it's in the documentation http://www.digitalmars.com/d/template.html template genericFunction (T) { void genericFunction(T p1, T p2, ..., T pN) { } } genericFunction!(list!(int))(...);Tom
Ok, I read the docs but the syntax was not so clear to me. Anyway, the C++ syntax (not referring about <>) is a lot better in the sense that you are not bound to name your template:
If you have a single member in the template, you don't have to./////////////////////////////////////// template genericFunctions(T) { T genericFunction1() {return T.max;} T genericFunction2() {return T.min;} .. } toString( genericFunctions.genericFunction1!(int)() ); toString( genericFunctions.genericFunction2!(int)() );
And that could be rewritten as: template genericFunction1(T) { T genericFunction1() { return T.max; } } template genericFunction2(T) { T genericFunction2() { return T.min; } } toString(genericFunction1!(int)); toString(genericFunction2!(int));.. /////////////////////////////////////// It just looks ugly! What about having some kind of anonymous template. (Please correct me if i'm wrong)
Do you mean implicit template instantiation? Apparently it'll be in a future version.Tom
Oct 31 2005
In article <dk5min$1h46$1 digitaldaemon.com>, John C says..."Tomás Rossi" <Tomás_member pathlink.com> wrote in message news:dk5lqe$1gar$1 digitaldaemon.com...In article <dk52us$qpb$1 digitaldaemon.com>, John C says..."Tomás Rossi" <Tomás_member pathlink.com> wrote in message news:dk50a0$mmk$1 digitaldaemon.com...In C++ one could do this: template <class T> void genericFunction<T>(someParam1, someParam2, ..., someParamN) {...generic algorithm...} and then: .. genericFunction< list<int> >(blah blah ...); .. Is this possible in D?
Yes, it's in the documentation http://www.digitalmars.com/d/template.html template genericFunction (T) { void genericFunction(T p1, T p2, ..., T pN) { } } genericFunction!(list!(int))(...);Tom
Ok, I read the docs but the syntax was not so clear to me. Anyway, the C++ syntax (not referring about <>) is a lot better in the sense that you are not bound to name your template:
If you have a single member in the template, you don't have to.
How is that? You don't have to do it when using the function, but you have to name your template the same as your templated function./////////////////////////////////////// template genericFunctions(T) { T genericFunction1() {return T.max;} T genericFunction2() {return T.min;} .. } toString( genericFunctions.genericFunction1!(int)() ); toString( genericFunctions.genericFunction2!(int)() );
And that could be rewritten as: template genericFunction1(T) { T genericFunction1() { return T.max; } } template genericFunction2(T) { T genericFunction2() { return T.min; } } toString(genericFunction1!(int)); toString(genericFunction2!(int));.. /////////////////////////////////////// It just looks ugly! What about having some kind of anonymous template. (Please correct me if i'm wrong)
Do you mean implicit template instantiation? Apparently it'll be in a future version.Tom
I was talking about something like this: template (T) { T genericFunction1() {...} T genericFunction2() {...} } Doing: template AAA(T) { T AAA() {...} } template BBB(T) { T BBB() {...} } .. is uglier than C++s: template <class T> T AAA() {...} template <class T> T BBB() {...} .. in the sense that you have to write AAA two times! Tom
Oct 31 2005
If you have a single member in the template, you don't have to.
How is that? You don't have to do it when using the function, but you have to name your template the same as your templated function.
It's to do with templates having their own scope, which makes them akin to modules.I was talking about something like this: template (T) { T genericFunction1() {...} T genericFunction2() {...} } Doing: template AAA(T) { T AAA() {...} } template BBB(T) { T BBB() {...} } .. is uglier than C++s: template <class T> T AAA() {...} template <class T> T BBB() {...} .. in the sense that you have to write AAA two times!
Some here have asked for this requirement to be removed for templated functions.Tom
Oct 31 2005
On Mon, 31 Oct 2005 17:55:26 +0000 (UTC), Tomás Rossi wrote:In article <dk52us$qpb$1 digitaldaemon.com>, John C says..."Tomás Rossi" <Tomás_member pathlink.com> wrote in message news:dk50a0$mmk$1 digitaldaemon.com...In C++ one could do this: template <class T> void genericFunction<T>(someParam1, someParam2, ..., someParamN) {...generic algorithm...} and then: .. genericFunction< list<int> >(blah blah ...); .. Is this possible in D?
Yes, it's in the documentation http://www.digitalmars.com/d/template.html template genericFunction (T) { void genericFunction(T p1, T p2, ..., T pN) { } } genericFunction!(list!(int))(...);Tom
Ok, I read the docs but the syntax was not so clear to me. Anyway, the C++ syntax (not referring about <>) is a lot better in the sense that you are not bound to name your template: /////////////////////////////////////// template genericFunctions(T) { T genericFunction1() {return T.max;} T genericFunction2() {return T.min;} .. } toString( genericFunctions.genericFunction1!(int)() ); toString( genericFunctions.genericFunction2!(int)() ); .. /////////////////////////////////////// It just looks ugly!
Yes it does. However Walter's suggested solution is to use the 'alias' declaration. template genericFunctions(T) { T genericFunction1() {return T.max;} T genericFunction2() {return T.min;} } // Define some easier names to type and read. alias genericFunctions!(int).genericFunction1 gf1; alias genericFunctions!(int).genericFunction2 gf2; // Show them in use. void main() { gf1(); gf2(); } -- Derek Parnell Melbourne, Australia 1/11/2005 8:30:53 AM
Oct 31 2005
In article <1vo72jbc04tgw.gwxz3kffp4gh.dlg 40tude.net>, Derek Parnell says...On Mon, 31 Oct 2005 17:55:26 +0000 (UTC), Tomás Rossi wrote:In article <dk52us$qpb$1 digitaldaemon.com>, John C says..."Tomás Rossi" <Tomás_member pathlink.com> wrote in message news:dk50a0$mmk$1 digitaldaemon.com...In C++ one could do this: template <class T> void genericFunction<T>(someParam1, someParam2, ..., someParamN) {...generic algorithm...} and then: .. genericFunction< list<int> >(blah blah ...); .. Is this possible in D?
Yes, it's in the documentation http://www.digitalmars.com/d/template.html template genericFunction (T) { void genericFunction(T p1, T p2, ..., T pN) { } } genericFunction!(list!(int))(...);Tom
Ok, I read the docs but the syntax was not so clear to me. Anyway, the C++ syntax (not referring about <>) is a lot better in the sense that you are not bound to name your template: /////////////////////////////////////// template genericFunctions(T) { T genericFunction1() {return T.max;} T genericFunction2() {return T.min;} .. } toString( genericFunctions.genericFunction1!(int)() ); toString( genericFunctions.genericFunction2!(int)() ); .. /////////////////////////////////////// It just looks ugly!
Yes it does. However Walter's suggested solution is to use the 'alias' declaration. template genericFunctions(T) { T genericFunction1() {return T.max;} T genericFunction2() {return T.min;} } // Define some easier names to type and read. alias genericFunctions!(int).genericFunction1 gf1; alias genericFunctions!(int).genericFunction2 gf2; // Show them in use. void main() { gf1(); gf2(); }
The same shit with different color would say my grandfather. :) That solution is a little ugly also and very old fashioned. Since D proclaims to be the cure for mosts of C++ syntax diseases (well, this is what i got at least), i can't see why do i have to appeal to this kind of "C++ style" workarounds. Besides, i don't see (and correct me please in other case) a good reason to dismiss a more elegant solution (builded in the language itself, like other similar problematics were faced), at least in some distant future. Suppose you have this: template GenericFunctions(T) { void doThis() {...} void doThat() {...} T getFoo() {...} void takeFoo(T t) {...} void yourSister() {...} void myCousin() {...} ..etc... } Would you alias one and all? Would you write a template with the func. name for everyone? Would you explicitly use GenericFunctions!(T).func()? Suppose that the language gives you this alternative: template(T) { void doThis() {...} void doThat() {...} T getFoo() {...} void takeFoo(T t) {...} void yourSister() {...} void myCousin() {...} ..etc... } All the above problems are resolved.-- Derek Parnell Melbourne, Australia 1/11/2005 8:30:53 AM
Hope i had maked my point. Tom BsAs, Argentina PS: Sorry for my poor English.
Oct 31 2005
Tomás Rossi wrote:In article <1vo72jbc04tgw.gwxz3kffp4gh.dlg 40tude.net>, Derek Parnell says...On Mon, 31 Oct 2005 17:55:26 +0000 (UTC), Tomás Rossi wrote:In article <dk52us$qpb$1 digitaldaemon.com>, John C says..."Tomás Rossi" <Tomás_member pathlink.com> wrote in message news:dk50a0$mmk$1 digitaldaemon.com...In C++ one could do this: template <class T> void genericFunction<T>(someParam1, someParam2, ..., someParamN) {...generic algorithm...} and then: .. genericFunction< list<int> >(blah blah ...); .. Is this possible in D?
Yes, it's in the documentation http://www.digitalmars.com/d/template.html template genericFunction (T) { void genericFunction(T p1, T p2, ..., T pN) { } } genericFunction!(list!(int))(...);Tom
Anyway, the C++ syntax (not referring about <>) is a lot better in the sense that you are not bound to name your template: /////////////////////////////////////// template genericFunctions(T) { T genericFunction1() {return T.max;} T genericFunction2() {return T.min;} .. } toString( genericFunctions.genericFunction1!(int)() ); toString( genericFunctions.genericFunction2!(int)() ); .. /////////////////////////////////////// It just looks ugly!
Yes it does. However Walter's suggested solution is to use the 'alias' declaration. template genericFunctions(T) { T genericFunction1() {return T.max;} T genericFunction2() {return T.min;} } // Define some easier names to type and read. alias genericFunctions!(int).genericFunction1 gf1; alias genericFunctions!(int).genericFunction2 gf2; // Show them in use. void main() { gf1(); gf2(); }
The same shit with different color would say my grandfather. :) That solution is a little ugly also and very old fashioned. Since D proclaims to be the cure for mosts of C++ syntax diseases (well, this is what i got at least), i can't see why do i have to appeal to this kind of "C++ style" workarounds. Besides, i don't see (and correct me please in other case) a good reason to dismiss a more elegant solution (builded in the language itself, like other similar problematics were faced), at least in some distant future. Suppose you have this: template GenericFunctions(T) { void doThis() {...} void doThat() {...} T getFoo() {...} void takeFoo(T t) {...} void yourSister() {...} void myCousin() {...} ...etc... } Would you alias one and all? Would you write a template with the func. name for everyone? Would you explicitly use GenericFunctions!(T).func()?
use that.Suppose that the language gives you this alternative: template(T) { void doThis() {...} void doThat() {...} T getFoo() {...} void takeFoo(T t) {...} void yourSister() {...} void myCousin() {...} ...etc... } All the above problems are resolved.
And in this case how would you instanciate the template or access any of those functions if the template is anonymous? -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
Nov 01 2005
In article <dk7d63$2pfk$1 digitaldaemon.com>, Bruno Medeiros says...Tomás Rossi wrote:In article <1vo72jbc04tgw.gwxz3kffp4gh.dlg 40tude.net>, Derek Parnell says...On Mon, 31 Oct 2005 17:55:26 +0000 (UTC), Tomás Rossi wrote:In article <dk52us$qpb$1 digitaldaemon.com>, John C says..."Tomás Rossi" <Tomás_member pathlink.com> wrote in message news:dk50a0$mmk$1 digitaldaemon.com...In C++ one could do this: template <class T> void genericFunction<T>(someParam1, someParam2, ..., someParamN) {...generic algorithm...} and then: .. genericFunction< list<int> >(blah blah ...); .. Is this possible in D?
Yes, it's in the documentation http://www.digitalmars.com/d/template.html template genericFunction (T) { void genericFunction(T p1, T p2, ..., T pN) { } } genericFunction!(list!(int))(...);Tom
Anyway, the C++ syntax (not referring about <>) is a lot better in the sense that you are not bound to name your template: /////////////////////////////////////// template genericFunctions(T) { T genericFunction1() {return T.max;} T genericFunction2() {return T.min;} .. } toString( genericFunctions.genericFunction1!(int)() ); toString( genericFunctions.genericFunction2!(int)() ); .. /////////////////////////////////////// It just looks ugly!
Yes it does. However Walter's suggested solution is to use the 'alias' declaration. template genericFunctions(T) { T genericFunction1() {return T.max;} T genericFunction2() {return T.min;} } // Define some easier names to type and read. alias genericFunctions!(int).genericFunction1 gf1; alias genericFunctions!(int).genericFunction2 gf2; // Show them in use. void main() { gf1(); gf2(); }
The same shit with different color would say my grandfather. :) That solution is a little ugly also and very old fashioned. Since D proclaims to be the cure for mosts of C++ syntax diseases (well, this is what i got at least), i can't see why do i have to appeal to this kind of "C++ style" workarounds. Besides, i don't see (and correct me please in other case) a good reason to dismiss a more elegant solution (builded in the language itself, like other similar problematics were faced), at least in some distant future. Suppose you have this: template GenericFunctions(T) { void doThis() {...} void doThat() {...} T getFoo() {...} void takeFoo(T t) {...} void yourSister() {...} void myCousin() {...} ...etc... } Would you alias one and all? Would you write a template with the func. name for everyone? Would you explicitly use GenericFunctions!(T).func()?
use that.Suppose that the language gives you this alternative: template(T) { void doThis() {...} void doThat() {...} T getFoo() {...} void takeFoo(T t) {...} void yourSister() {...} void myCousin() {...} ...etc... } All the above problems are resolved.
And in this case how would you instanciate the template or access any of those functions if the template is anonymous?
For example: takeFoo!(int)(34); char c = getFoo!(char)(); myCousin!(list!(ulong))(); etc.-- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
Tom
Nov 01 2005
In article <dk7d63$2pfk$1 digitaldaemon.com>, Bruno Medeiros says...Tomás Rossi wrote:Suppose you have this: template GenericFunctions(T) { void doThis() {...} void doThat() {...} T getFoo() {...} void takeFoo(T t) {...} void yourSister() {...} void myCousin() {...} ...etc... } Would you alias one and all? Would you write a template with the func. name for everyone? Would you explicitly use GenericFunctions!(T).func()?
use that.
The with keyword can also be useful for specifying a template instantiation. /Oskar
Nov 01 2005
In article <dk7hfu$2sud$1 digitaldaemon.com>, Oskar Linde says...In article <dk7d63$2pfk$1 digitaldaemon.com>, Bruno Medeiros says...Tomás Rossi wrote:Suppose you have this: template GenericFunctions(T) { void doThis() {...} void doThat() {...} T getFoo() {...} void takeFoo(T t) {...} void yourSister() {...} void myCousin() {...} ...etc... } Would you alias one and all? Would you write a template with the func. name for everyone? Would you explicitly use GenericFunctions!(T).func()?
use that.
The with keyword can also be useful for specifying a template instantiation.
Ok with all those solutions, i'm sure they work fine, but i can't see why there can't be anonymous templates. In fact mixins would do similar job, for example: template Generics(T) { T doThis() {return T.max;} void doThat() {} } void someFunc() { mixin Generics!(int); writefln(toString(doThis())); } but it'd be very nice if i just could do this: template(T) { T doThis() {return T.max;} void doThat() {} } void someFunc() { writefln(toString(doThis!(int)())); }/Oskar
Tom
Nov 01 2005
Tomás Rossi wrote:In article <1vo72jbc04tgw.gwxz3kffp4gh.dlg 40tude.net>, Derek Parnell says...On Mon, 31 Oct 2005 17:55:26 +0000 (UTC), Tomás Rossi wrote:In article <dk52us$qpb$1 digitaldaemon.com>, John C says..."Tomás Rossi" <Tomás_member pathlink.com> wrote in message news:dk50a0$mmk$1 digitaldaemon.com...In C++ one could do this: template <class T> void genericFunction<T>(someParam1, someParam2, ..., someParamN) {...generic algorithm...} and then: .. genericFunction< list<int> >(blah blah ...); .. Is this possible in D?
Yes, it's in the documentation http://www.digitalmars.com/d/template.html template genericFunction (T) { void genericFunction(T p1, T p2, ..., T pN) { } } genericFunction!(list!(int))(...);Tom
Anyway, the C++ syntax (not referring about <>) is a lot better in the sense that you are not bound to name your template: /////////////////////////////////////// template genericFunctions(T) { T genericFunction1() {return T.max;} T genericFunction2() {return T.min;} .. } toString( genericFunctions.genericFunction1!(int)() ); toString( genericFunctions.genericFunction2!(int)() ); .. /////////////////////////////////////// It just looks ugly!
Yes it does. However Walter's suggested solution is to use the 'alias' declaration. template genericFunctions(T) { T genericFunction1() {return T.max;} T genericFunction2() {return T.min;} } // Define some easier names to type and read. alias genericFunctions!(int).genericFunction1 gf1; alias genericFunctions!(int).genericFunction2 gf2; // Show them in use. void main() { gf1(); gf2(); }
The same shit with different color would say my grandfather. :) That solution is a little ugly also and very old fashioned. Since D proclaims to be the cure for mosts of C++ syntax diseases (well, this is what i got at least), i can't see why do i have to appeal to this kind of "C++ style" workarounds. Besides, i don't see (and correct me please in other case) a good reason to dismiss a more elegant solution (builded in the language itself, like other similar problematics were faced), at least in some distant future. Suppose you have this: template GenericFunctions(T) { void doThis() {...} void doThat() {...} T getFoo() {...} void takeFoo(T t) {...} void yourSister() {...} void myCousin() {...} ..etc... } Would you alias one and all? Would you write a template with the func. name for everyone? Would you explicitly use GenericFunctions!(T).func()? Suppose that the language gives you this alternative: template(T) { void doThis() {...} void doThat() {...} T getFoo() {...} void takeFoo(T t) {...} void yourSister() {...} void myCousin() {...} ..etc... } All the above problems are resolved.-- Derek Parnell Melbourne, Australia 1/11/2005 8:30:53 AM
Hope i had maked my point. Tom BsAs, Argentina PS: Sorry for my poor English.
One option is simply to mixin the template: mixin GenericFunctions!(int); then you can simply call the functions you want. doThis(); doThat(); Of course with name clashes(like mixing in the template twice) you will need to use with or alias. -DavidM
Nov 01 2005
In article <dk7n87$ac$1 digitaldaemon.com>, David Medlock says...Tomás Rossi wrote:In article <1vo72jbc04tgw.gwxz3kffp4gh.dlg 40tude.net>, Derek Parnell says...On Mon, 31 Oct 2005 17:55:26 +0000 (UTC), Tomás Rossi wrote:In article <dk52us$qpb$1 digitaldaemon.com>, John C says..."Tomás Rossi" <Tomás_member pathlink.com> wrote in message news:dk50a0$mmk$1 digitaldaemon.com...In C++ one could do this: template <class T> void genericFunction<T>(someParam1, someParam2, ..., someParamN) {...generic algorithm...} and then: .. genericFunction< list<int> >(blah blah ...); .. Is this possible in D?
Yes, it's in the documentation http://www.digitalmars.com/d/template.html template genericFunction (T) { void genericFunction(T p1, T p2, ..., T pN) { } } genericFunction!(list!(int))(...);Tom
Anyway, the C++ syntax (not referring about <>) is a lot better in the sense that you are not bound to name your template: /////////////////////////////////////// template genericFunctions(T) { T genericFunction1() {return T.max;} T genericFunction2() {return T.min;} .. } toString( genericFunctions.genericFunction1!(int)() ); toString( genericFunctions.genericFunction2!(int)() ); .. /////////////////////////////////////// It just looks ugly!
Yes it does. However Walter's suggested solution is to use the 'alias' declaration. template genericFunctions(T) { T genericFunction1() {return T.max;} T genericFunction2() {return T.min;} } // Define some easier names to type and read. alias genericFunctions!(int).genericFunction1 gf1; alias genericFunctions!(int).genericFunction2 gf2; // Show them in use. void main() { gf1(); gf2(); }
The same shit with different color would say my grandfather. :) That solution is a little ugly also and very old fashioned. Since D proclaims to be the cure for mosts of C++ syntax diseases (well, this is what i got at least), i can't see why do i have to appeal to this kind of "C++ style" workarounds. Besides, i don't see (and correct me please in other case) a good reason to dismiss a more elegant solution (builded in the language itself, like other similar problematics were faced), at least in some distant future. Suppose you have this: template GenericFunctions(T) { void doThis() {...} void doThat() {...} T getFoo() {...} void takeFoo(T t) {...} void yourSister() {...} void myCousin() {...} ..etc... } Would you alias one and all? Would you write a template with the func. name for everyone? Would you explicitly use GenericFunctions!(T).func()? Suppose that the language gives you this alternative: template(T) { void doThis() {...} void doThat() {...} T getFoo() {...} void takeFoo(T t) {...} void yourSister() {...} void myCousin() {...} ..etc... } All the above problems are resolved.-- Derek Parnell Melbourne, Australia 1/11/2005 8:30:53 AM
Hope i had maked my point. Tom BsAs, Argentina PS: Sorry for my poor English.
One option is simply to mixin the template: mixin GenericFunctions!(int); then you can simply call the functions you want. doThis(); doThat(); Of course with name clashes(like mixing in the template twice) you will need to use with or alias. -DavidM
Yap... i knew that one :) digitalmars.D/29592 Tom
Nov 01 2005
In article <dk6p11$28p0$1 digitaldaemon.com>, Tomás Rossi says...In article <1vo72jbc04tgw.gwxz3kffp4gh.dlg 40tude.net>, Derek Parnell says...On Mon, 31 Oct 2005 17:55:26 +0000 (UTC), Tomás Rossi wrote:In article <dk52us$qpb$1 digitaldaemon.com>, John C says..."Tomás Rossi" <Tomás_member pathlink.com> wrote in message news:dk50a0$mmk$1 digitaldaemon.com...In C++ one could do this: template <class T> void genericFunction<T>(someParam1, someParam2, ..., someParamN) {...generic algorithm...} and then: .. genericFunction< list<int> >(blah blah ...); .. Is this possible in D?
Yes, it's in the documentation http://www.digitalmars.com/d/template.html template genericFunction (T) { void genericFunction(T p1, T p2, ..., T pN) { } } genericFunction!(list!(int))(...);Tom
Ok, I read the docs but the syntax was not so clear to me. Anyway, the C++ syntax (not referring about <>) is a lot better in the sense that you are not bound to name your template: /////////////////////////////////////// template genericFunctions(T) { T genericFunction1() {return T.max;} T genericFunction2() {return T.min;} .. } toString( genericFunctions.genericFunction1!(int)() ); toString( genericFunctions.genericFunction2!(int)() ); .. /////////////////////////////////////// It just looks ugly!
Yes it does. However Walter's suggested solution is to use the 'alias' declaration. template genericFunctions(T) { T genericFunction1() {return T.max;} T genericFunction2() {return T.min;} } // Define some easier names to type and read. alias genericFunctions!(int).genericFunction1 gf1; alias genericFunctions!(int).genericFunction2 gf2; // Show them in use. void main() { gf1(); gf2(); }
The same shit with different color would say my grandfather. :) That solution is a little ugly also and very old fashioned. Since D proclaims to be the cure for mosts of C++ syntax diseases (well, this is what i got at least), i can't see why do i have to appeal to this kind of "C++ style" workarounds. Besides, i don't see (and correct me please in other case) a good reason to dismiss a more elegant solution (builded in the language itself, like other similar problematics were faced), at least in some distant future. Suppose you have this: template GenericFunctions(T) { void doThis() {...} void doThat() {...} T getFoo() {...} void takeFoo(T t) {...} void yourSister() {...} void myCousin() {...} ..etc... } Would you alias one and all? Would you write a template with the func. name for everyone? Would you explicitly use GenericFunctions!(T).func()? Suppose that the language gives you this alternative: template(T) { void doThis() {...} void doThat() {...} T getFoo() {...} void takeFoo(T t) {...} void yourSister() {...} void myCousin() {...} ..etc... } All the above problems are resolved.-- Derek Parnell Melbourne, Australia 1/11/2005 8:30:53 AM
Hope i had maked my point. Tom BsAs, Argentina PS: Sorry for my poor English.
I want to write a Delegate class that with multi-dispatch, like C#: Delegate!(void delegate()) dele; dele += obj.func; dele += obj.func1; dele (); Delegate!(void delegate(char[], int, float, short, .......)) dele1; dele1 += obj.funca; dele1 += obj.funca1; dele1 (.........); I think that is difficult. In C++, I can do this: void test(int, int); void test1(short, short); Delegate<void(short, char)> dele; dele += test; dele += test1; The function "operator +=" is a template function, it can deduct the types of arguments, then I can use the types and process them. Of course, that need to use template specialization, it depends on the count of function arguments. In D, I don't know how to do it. PS: Sorry for my poor English too.
Nov 04 2005
I want to write a Delegate class that with multi-dispatch, like C#: Delegate!(void delegate()) dele; dele += obj.func; dele += obj.func1; dele (); Delegate!(void delegate(char[], int, float, short, .......)) dele1; dele1 += obj.funca; dele1 += obj.funca1; dele1 (.........); I think that is difficult. In C++, I can do this: void test(int, int); void test1(short, short); Delegate<void(short, char)> dele; dele += test; dele += test1; The function "operator +=" is a template function, it can deduct the types of arguments, then I can use the types and process them. Of course, that need to use template specialization, it depends on the count of function arguments. In D, I don't know how to do it. PS: Sorry for my poor English too.
There's a few so-called multicast delegate libraries floating around. MinWin contains a good implementation http://home.comcast.net/~benhinkle/minwin/. There are also some signal/slot libraries, for example at http://www.uwesalomon.de/code/indigo/files2/index-txt.html. If you need the overloaded += behaviour, I've pasted my own version, which extends MinWin's, below. To declare a multicast delegate: alias MulticastDelegate!(void, char[]) StringDisplayHandler; To use it: void stringDisplayFunc(char[] s) { writefln(s); } StringDisplayHandler handler; handler += delegate void(char[] s) { writefln(s); }; handler += &stringDisplayFunc; handler("Hello World"); Source: template MethodWrapperBase(TDelegate, TFunction) { public bool isStatic; package union { TDelegate delegate_; struct { void* p; TFunction function_; } } public static MethodWrapper wrap(TDelegate d) { MethodWrapper m; m.delegate_ = d; return m; } public static MethodWrapper wrap(TFunction f) { MethodWrapper m; m.isStatic = true; m.function_ = f; return m; } void clear() { function_ = null; delegate_ = null; } } struct MethodWrapper(R) { alias R delegate() TDelegate; alias R function() TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall() { if (isStatic) { if (function_ != null) return function_(); return R.init; } if (delegate_ != null) return delegate_(); return R.init; } } struct MethodWrapper(R : void) { alias R delegate() TDelegate; alias R function() TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall() { if (isStatic) { if (function_ != null) function_(); } if (delegate_ != null) delegate_(); } } struct MethodWrapper(R, T) { alias R delegate(T) TDelegate; alias R function(T) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T arg) { if (isStatic) { if (function_ != null) return function_(arg); return R.init; } if (delegate_ != null) return delegate_(arg); return R.init; } } struct MethodWrapper(R : void, T) { alias R delegate(T) TDelegate; alias R function(T) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T arg) { if (isStatic) { if (function_ != null) function_(arg); } if (delegate_ != null) delegate_(arg); } } struct MethodWrapper(R, T0, T1) { alias R delegate(T0, T1) TDelegate; alias R function(T0, T1) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T0 arg0, T1 arg1) { if (isStatic) { if (function_ != null) return function_(arg0, arg1); return R.init; } if (delegate_ != null) return delegate_(arg0, arg1); return R.init; } } struct MethodWrapper(R : void, T0, T1) { alias R delegate(T0, T1) TDelegate; alias R function(T0, T1) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T0 arg0, T1 arg1) { if (isStatic) { if (function_ != null) function_(arg0, arg1); } if (delegate_ != null) delegate_(arg0, arg1); } } struct MethodWrapper(R, T0, T1, T2) { alias R delegate(T0, T1, T2) TDelegate; alias R function(T0, T1, T2) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T0 arg0, T1 arg1, T2 arg2) { if (isStatic) { if (function_ != null) return function_(arg0, arg1, arg2); return R.init; } if (delegate_ != null) return delegate_(arg0, arg1, arg2); return R.init; } } struct MethodWrapper(R : void, T0, T1, T2) { alias R delegate(T0, T1, T2) TDelegate; alias R function(T0, T1, T2) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T0 arg0, T1 arg1, T2 arg2) { if (isStatic) { if (function_ != null) function_(arg0, arg1, arg2); } if (delegate_ != null) delegate_(arg0, arg1, arg2); } } struct MethodWrapper(R, T0, T1, T2, T3) { alias R delegate(T0, T1, T2, T3) TDelegate; alias R function(T0, T1, T2, T3) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T0 arg0, T1 arg1, T2 arg2, T3 arg3) { if (isStatic) { if (function_ != null) return function_(arg0, arg1, arg2, arg3); return R.init; } if (delegate_ != null) return delegate_(arg0, arg1, arg2, arg3); return R.init; } } struct MethodWrapper(R : void, T0, T1, T2, T3) { alias R delegate(T0, T1, T2, T3) TDelegate; alias R function(T0, T1, T2, T3) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T0 arg0, T1 arg1, T2 arg2, T3 arg3) { if (isStatic) { if (function_ != null) function_(arg0, arg1, arg2, arg3); } if (delegate_ != null) delegate_(arg0, arg1, arg2, arg3); } } struct MethodWrapper(R, T0, T1, T2, T3, T4) { alias R delegate(T0, T1, T2, T3, T4) TDelegate; alias R function(T0, T1, T2, T3, T4) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { if (isStatic) { if (function_ != null) return function_(arg0, arg1, arg2, arg3, arg4); return R.init; } if (delegate_ != null) return delegate_(arg0, arg1, arg2, arg3, arg4); return R.init; } } struct MethodWrapper(R : void, T0, T1, T2, T3, T4) { alias R delegate(T0, T1, T2, T3, T4) TDelegate; alias R function(T0, T1, T2, T3, T4) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { if (isStatic) { if (function_ != null) function_(arg0, arg1, arg2, arg3, arg4); } if (delegate_ != null) delegate_(arg0, arg1, arg2, arg3, arg4); } } template MulticastDelegateBase() { public void add(TDelegate d) { if (d == null) return; int len = methods_.length; int n = len - 1; while (n >= 0 && methods_[n].delegate_ == null) --n; if (n < len - 1) methods_[n + 1] = TMethodWrapper.wrap(d); else methods_ ~= TMethodWrapper.wrap(d); } public void opAddAssign(TDelegate d) { add(d); } public void remove(TDelegate d) { if (methods_.length == 0) return; bool found; for (int i = 0; i < methods_.length - 1; ++i) { if (!found && methods_[i].delegate_ is d) found = true; if (found) methods_[i] = methods_[i + 1]; if (methods_[i].delegate_ is null) break; } if (found || methods_[length - 1].delegate_ is d) methods_[length - 1].clear(); } public void opSubAssign(TDelegate d) { remove(d); } public void remove(TFunction f) { if (methods_.length == 0) return; bool found; for (int i = 0; i < methods_.length - 1; ++i) { if (!found && methods_[i].function_ is f) found = true; if (found) methods_[i] = methods_[i + 1]; if (methods_[i].delegate_ is null) break; } if (found || methods_[length - 1].function_ is f) methods_[length - 1].clear(); } public void opSubAssign(TFunction f) { remove(f); } public bool isEmpty() { if (methods_.length == 0) return true; else if (methods_[0].delegate_ == null) return true; return false; } } template MulticastDelegateGenericMixins() { alias TMethodWrapper.TDelegate TDelegate; alias TMethodWrapper.TFunction TFunction; package TMethodWrapper[] methods_; mixin MulticastDelegateBase; } template MulticastDelegateMixins(R) { alias MethodWrapper!(R) TMethodWrapper; mixin MulticastDelegateGenericMixins; } template MulticastDelegateMixins(R, T) { alias MethodWrapper!(R, T) TMethodWrapper; mixin MulticastDelegateGenericMixins; } template MulticastDelegateMixins(R, T0, T1) { alias MethodWrapper!(R, T0, T1) TMethodWrapper; mixin MulticastDelegateGenericMixins; } template MulticastDelegateMixins(R, T0, T1, T2) { alias MethodWrapper!(R, T0, T1, T2) TMethodWrapper; mixin MulticastDelegateGenericMixins; } template MulticastDelegateMixins(R, T0, T1, T2, T3) { alias MethodWrapper!(R, T0, T1, T2, T3) TMethodWrapper; mixin MulticastDelegateGenericMixins; } template MulticastDelegateMixins(R, T0, T1, T2, T3, T4) { alias MethodWrapper!(R, T0, T1, T2, T3, T4) TMethodWrapper; mixin MulticastDelegateGenericMixins; } struct MulticastDelegate(R) { mixin MulticastDelegateMixins!(R); public R opCall() { for (int i = 0; i < methods_.length - 1; i++) methods_[i](); return methods_[$ - 1](); } } struct MulticastDelegate(R : void) { mixin MulticastDelegateMixins!(R); public R opCall() { foreach (TMethodWrapper method; methods_) method(); } } struct MulticastDelegate(R, T) { mixin MulticastDelegateMixins!(R, T); public R opCall(T arg) { for (int i = 0; i < methods_.length - 1; i++) methods_[i](arg); return methods_[$ - 1](arg); } } struct MulticastDelegate(R : void, T) { mixin MulticastDelegateMixins!(R, T); public R opCall(T arg) { foreach (TMethodWrapper method; methods_) method(arg); } } struct MulticastDelegate(R, T0, T1) { mixin MulticastDelegateMixins!(R, T0, T1); public R opCall(T0 arg0, T1 arg1) { for (int i = 0; i < methods_.length - 1; i++) methods_[i](arg0, arg1); return methods_[$ - 1](arg0, arg1); } } struct MulticastDelegate(R : void, T0, T1) { mixin MulticastDelegateMixins!(R, T0, T1); public R opCall(T0 arg0, T1 arg1) { foreach (TMethodWrapper method; methods_) method(arg0, arg1); } } struct MulticastDelegate(R, T0, T1, T2) { mixin MulticastDelegateMixins!(R, T0, T1, T2); public R opCall(T0 arg0, T1 arg1, T2 arg2) { for (int i = 0; i < methods_.length - 1; i++) methods_[i](arg0, arg1, arg2); return methods_[$ - 1](arg0, arg1, arg2); } } struct MulticastDelegate(R : void, T0, T1, T2) { mixin MulticastDelegateMixins!(R, T0, T1, T2); public R opCall(T0 arg0, T1 arg1, T2 arg2) { foreach (TMethodWrapper method; methods_) method(arg0, arg1, arg2); } } struct MulticastDelegate(R, T0, T1, T2, T3) { mixin MulticastDelegateMixins!(R, T0, T1, T2, T3); public R opCall(T0 arg0, T1 arg1, T2 arg2, T3 arg3) { for (int i = 0; i < methods_.length - 1; i++) methods_[i](arg0, arg1, arg2, arg3); return methods_[$ - 1](arg0, arg1, arg2, arg3); } } struct MulticastDelegate(R : void, T0, T1, T2, T3) { mixin MulticastDelegateMixins!(R, T0, T1, T2, T3); public R opCall(T0 arg0, T1 arg1, T2 arg2, T3 arg3) { foreach (TMethodWrapper method; methods_) method(arg0, arg1, arg2, arg3); } } struct MulticastDelegate(R, T0, T1, T2, T3, T4) { mixin MulticastDelegateMixins!(R, T0, T1, T2, T3, T4); public R opCall(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { for (int i = 0; i < methods_.length - 1; i++) methods_[i](arg0, arg1, arg2, arg3, arg4); return methods_[$ - 1](arg0, arg1, arg2, arg3, arg4); } } struct MulticastDelegate(R : void, T0, T1, T2, T3, T4) { mixin MulticastDelegateMixins!(R, T0, T1, T2, T3, T4); public R opCall(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { foreach (TMethodWrapper method; methods_) method(arg0, arg1, arg2, arg3, arg4); } }
Nov 04 2005
In article <dkgd5c$2o1d$1 digitaldaemon.com>, John C says...There's a few so-called multicast delegate libraries floating around. MinWin contains a good implementation http://home.comcast.net/~benhinkle/minwin/. There are also some signal/slot libraries, for example at http://www.uwesalomon.de/code/indigo/files2/index-txt.html. If you need the overloaded += behaviour, I've pasted my own version, which extends MinWin's, below. To declare a multicast delegate: alias MulticastDelegate!(void, char[]) StringDisplayHandler; To use it: void stringDisplayFunc(char[] s) { writefln(s); } StringDisplayHandler handler; handler += delegate void(char[] s) { writefln(s); }; handler += &stringDisplayFunc; handler("Hello World");
Thanks. It works well!
Nov 04 2005
In article <dkgtg6$4qr$1 digitaldaemon.com>, cpunion gmail.com says...In article <dkgd5c$2o1d$1 digitaldaemon.com>, John C says...There's a few so-called multicast delegate libraries floating around. MinWin contains a good implementation http://home.comcast.net/~benhinkle/minwin/. There are also some signal/slot libraries, for example at http://www.uwesalomon.de/code/indigo/files2/index-txt.html. If you need the overloaded += behaviour, I've pasted my own version, which extends MinWin's, below. To declare a multicast delegate: alias MulticastDelegate!(void, char[]) StringDisplayHandler; To use it: void stringDisplayFunc(char[] s) { writefln(s); } StringDisplayHandler handler; handler += delegate void(char[] s) { writefln(s); }; handler += &stringDisplayFunc; handler("Hello World");
Thanks. It works well!
The Boost::function can accept the compatible types, for example: int f1(int); // function type: int(int) short f2(double); // function type: short(double) struct functor // functor type: int(int) { int operator()(double){} }; functor f3; // functor object boost::function<int(int)> func; // function object, lick delegate, type: int(int) func = f1; // can accept int(int) func = f2; // can accept short(double) func = f3; // can accept functor(type: int(double)). In D, may be replaced with &f3.opCall? The function object can accept the compatible types, can resolve it in D? Thanks.
Nov 04 2005
<cpunion gmail.com> wrote in message news:dkhcob$gaa$1 digitaldaemon.com...In article <dkgtg6$4qr$1 digitaldaemon.com>, cpunion gmail.com says...In article <dkgd5c$2o1d$1 digitaldaemon.com>, John C says...There's a few so-called multicast delegate libraries floating around. MinWin contains a good implementation http://home.comcast.net/~benhinkle/minwin/. There are also some signal/slot libraries, for example at http://www.uwesalomon.de/code/indigo/files2/index-txt.html. If you need the overloaded += behaviour, I've pasted my own version, which extends MinWin's, below. To declare a multicast delegate: alias MulticastDelegate!(void, char[]) StringDisplayHandler; To use it: void stringDisplayFunc(char[] s) { writefln(s); } StringDisplayHandler handler; handler += delegate void(char[] s) { writefln(s); }; handler += &stringDisplayFunc; handler("Hello World");
Thanks. It works well!
The Boost::function can accept the compatible types, for example: int f1(int); // function type: int(int) short f2(double); // function type: short(double) struct functor // functor type: int(int) { int operator()(double){} }; functor f3; // functor object boost::function<int(int)> func; // function object, lick delegate, type: int(int) func = f1; // can accept int(int) func = f2; // can accept short(double) func = f3; // can accept functor(type: int(double)). In D, may be replaced with &f3.opCall? The function object can accept the compatible types, can resolve it in D? Thanks.
That's doubtful. I've not even seen functors in use in D like that, so don't think it's possible.
Nov 05 2005
In article <dkhtuh$1432$1 digitaldaemon.com>, John C says...That's doubtful. I've not even seen functors in use in D like that, so don't think it's possible.
Thanks. I think that not need that in D. :-)
Nov 05 2005









"John C" <johnch_atms hotmail.com> 