digitalmars.D - class template members (bug or feature?)
- Sean Kelly (14/14) Jun 15 2004 When trying to compile this code:
- Norbert Nemec (15/26) Jun 15 2004 The function fn conflicts with the template fn. Probably, what you want ...
- Sean Kelly (14/21) Jun 15 2004 Don't care if they can be made virtual. In this case I'm using private
- Norbert Nemec (7/34) Jun 16 2004 I.e. "one parameter and one argument set". The usual wording in C++ is t...
- Sean Kelly (13/17) Jun 16 2004 Yup. But just to be pedantic, I also tried this and was a bit surprised...
- Hauke Duden (7/30) Jun 16 2004 For this kind of thing you need to mix-in the template:
- Sean Kelly (21/50) Jun 16 2004 Thanks :) Now to see if you have an answer for what I'm really trying t...
- Hauke Duden (11/72) Jun 16 2004 Heh, I stumbled about this as well. Mixins work just like import does,
- Sean Kelly (40/49) Jun 16 2004 Oops! I just noticed that my previous example had an error--the return ...
When trying to compile this code: class MyClass { public: template fn( T ) { int fn( T t ) { return 1; } } int fn( int t ) { return 2; } } I get this error: test3.d(4): function fn conflicts with MyClass.fn(T) at test3.d(3) Why is there a conflict? The template isn't being instantiated, and even if it were instantiated for type int the calling conventions are different so I wouldn't expect to see this error. Both these problems go away if I change the name of the template or function so they don't conflict, but I'm still curious about whether this is intended behavior. Sean
Jun 15 2004
Sean Kelly wrote:When trying to compile this code: class MyClass { public: template fn( T ) { int fn( T t ) { return 1; } } int fn( int t ) { return 2; } } I get this error: test3.d(4): function fn conflicts with MyClass.fn(T) at test3.d(3)The function fn conflicts with the template fn. Probably, what you want to do is specialization: class MyClass { template fn( T ) { int fn( T t ) { return 1; } } template fn( T: int ) } { int fn( int t ) { return 2; } } } (hope this compiles - didn't check it. Just read it from the specs) In any case, I fear, what you are trying to do will not work, since a template cannot be used to add public (i.e. virtual) functions to a class. In any case, it has to be understood that a template is a language object - in this case with the name fn - even if it is not instantiated. It will be part of the namespace and can therefore conflict with other objects. The name of the function inside the template (which is identical in this case) is irrelevant in that respect.
Jun 15 2004
In article <cani18$nh$1 digitaldaemon.com>, Norbert Nemec says...In any case, I fear, what you are trying to do will not work, since a template cannot be used to add public (i.e. virtual) functions to a class.Don't care if they can be made virtual. In this case I'm using private templates and aliasing them for various types in order to avoid duplicated code for a set of overloaded functions.In any case, it has to be understood that a template is a language object - in this case with the name fn - even if it is not instantiated. It will be part of the namespace and can therefore conflict with other objects. The name of the function inside the template (which is identical in this case) is irrelevant in that respect.Certainly. Perhaps the problem is that I'm expecting templates to work as they do in C++, where a template functions are evaluated during overload resolution. In D, template functions actually define a separate namespace and it's this namespace that's conflicting with a function name in the same scope. I'll admit I'd be overjoyed if there were a shorthand way to write template functions similar to how class definitions can omit the "template" keyword--the current mechanism seems a bit clunky. But I suppose the shorthand used by template classes could be awkward to parse, as it would effectively result in a function with two separate parameter sets. Sean
Jun 15 2004
Sean Kelly wrote:In article <cani18$nh$1 digitaldaemon.com>, Norbert Nemec says...I.e. "one parameter and one argument set". The usual wording in C++ is that functions have arguments while templates have parameters. Anyhow: I agree that template functions are not very well supported in D. A suitable shorthand would be really helpful (no idea what it might look like), but even more important: *implicit instantiation* - anyhow that topic has been chewed over often enough in the past...In any case, I fear, what you are trying to do will not work, since a template cannot be used to add public (i.e. virtual) functions to a class.Don't care if they can be made virtual. In this case I'm using private templates and aliasing them for various types in order to avoid duplicated code for a set of overloaded functions.In any case, it has to be understood that a template is a language object - in this case with the name fn - even if it is not instantiated. It will be part of the namespace and can therefore conflict with other objects. The name of the function inside the template (which is identical in this case) is irrelevant in that respect.Certainly. Perhaps the problem is that I'm expecting templates to work as they do in C++, where a template functions are evaluated during overload resolution. In D, template functions actually define a separate namespace and it's this namespace that's conflicting with a function name in the same scope. I'll admit I'd be overjoyed if there were a shorthand way to write template functions similar to how class definitions can omit the "template" keyword--the current mechanism seems a bit clunky. But I suppose the shorthand used by template classes could be awkward to parse, as it would effectively result in a function with two separate parameter sets.
Jun 16 2004
In article <caplqu$24l$2 digitaldaemon.com>, Norbert Nemec says...Anyhow: I agree that template functions are not very well supported in D. A suitable shorthand would be really helpful (no idea what it might look like), but even more important: *implicit instantiation* - anyhow that topic has been chewed over often enough in the past...Yup. But just to be pedantic, I also tried this and was a bit surprised it failed: interface I { void fn( int ); } class C : I { template fnImpl(T) { void fnImpl( int ) {} } alias fnImpl!(int) fn; } with this error: test.d(5): class C 1interface function I.fn is not implemented Sean
Jun 16 2004
Sean Kelly wrote:In article <caplqu$24l$2 digitaldaemon.com>, Norbert Nemec says...For this kind of thing you need to mix-in the template: class C : I { template fnImpl(T) { void fn(int) {} } mixin fnImpl!(int); } HaukeAnyhow: I agree that template functions are not very well supported in D. A suitable shorthand would be really helpful (no idea what it might look like), but even more important: *implicit instantiation* - anyhow that topic has been chewed over often enough in the past...Yup. But just to be pedantic, I also tried this and was a bit surprised it failed: interface I { void fn( int ); } class C : I { template fnImpl(T) { void fnImpl( int ) {} } alias fnImpl!(int) fn; } with this error: test.d(5): class C 1interface function I.fn is not implemented
Jun 16 2004
In article <capo9l$6d9$1 digitaldaemon.com>, Hauke Duden says...Sean Kelly wrote:Thanks :) Now to see if you have an answer for what I'm really trying to do: interface I { void fn( int ); void fn( int* ); } class C( SomeT ) : I { template fnImpl(T) { int fn( int x ) { return fn( &x ); } } mixin fnImpl!(int); int fn( int* x ) { return 0; } } errors: test.d(6): class C 1interface function I.fn is not implemented test.d(6): class C 1interface function I.fn is not implemented test.d(7): function fn (int x) does not match argument types (int*) test.d(7): cannot implicitly convert int* to int Now obviously the overload resolution isn't looking outside the scope of fnImpl to find fn(float), but is this correct? It should be noted that if I make C a normal class rather than a template then I only get the first two errors. Adding 'public' doesn't help. SeanIn article <caplqu$24l$2 digitaldaemon.com>, Norbert Nemec says...For this kind of thing you need to mix-in the template: class C : I { template fnImpl(T) { void fn(int) {} } mixin fnImpl!(int); }Anyhow: I agree that template functions are not very well supported in D. A suitable shorthand would be really helpful (no idea what it might look like), but even more important: *implicit instantiation* - anyhow that topic has been chewed over often enough in the past...Yup. But just to be pedantic, I also tried this and was a bit surprised it failed: interface I { void fn( int ); } class C : I { template fnImpl(T) { void fnImpl( int ) {} } alias fnImpl!(int) fn; } with this error: test.d(5): class C 1interface function I.fn is not implemented
Jun 16 2004
Sean Kelly wrote:In article <capo9l$6d9$1 digitaldaemon.com>, Hauke Duden says...Heh, I stumbled about this as well. Mixins work just like import does, i.e. functions from different modules/mixins don't overload with each other by default. In other words, the problem is that you have a function with the same name ("fn") in both the mixin template and the class. To get this to work you have to add an alias for the mixin fn to the class. I.e. something like this (hopefully the syntax is correct - I've never used alias much): mixin fnImpl!(int) mixFn; alias mixFn.fn fn; HaukeSean Kelly wrote:Thanks :) Now to see if you have an answer for what I'm really trying to do: interface I { void fn( int ); void fn( int* ); } class C( SomeT ) : I { template fnImpl(T) { int fn( int x ) { return fn( &x ); } } mixin fnImpl!(int); int fn( int* x ) { return 0; } } errors: test.d(6): class C 1interface function I.fn is not implemented test.d(6): class C 1interface function I.fn is not implemented test.d(7): function fn (int x) does not match argument types (int*) test.d(7): cannot implicitly convert int* to int Now obviously the overload resolution isn't looking outside the scope of fnImpl to find fn(float), but is this correct? It should be noted that if I make C a normal class rather than a template then I only get the first two errors. Adding 'public' doesn't help.In article <caplqu$24l$2 digitaldaemon.com>, Norbert Nemec says...For this kind of thing you need to mix-in the template: class C : I { template fnImpl(T) { void fn(int) {} } mixin fnImpl!(int); }Anyhow: I agree that template functions are not very well supported in D. A suitable shorthand would be really helpful (no idea what it might look like), but even more important: *implicit instantiation* - anyhow that topic has been chewed over often enough in the past...Yup. But just to be pedantic, I also tried this and was a bit surprised it failed: interface I { void fn( int ); } class C : I { template fnImpl(T) { void fnImpl( int ) {} } alias fnImpl!(int) fn; } with this error: test.d(5): class C 1interface function I.fn is not implemented
Jun 16 2004
In article <capqje$a6f$1 digitaldaemon.com>, Hauke Duden says...Heh, I stumbled about this as well. Mixins work just like import does, i.e. functions from different modules/mixins don't overload with each other by default. In other words, the problem is that you have a function with the same name ("fn") in both the mixin template and the class. To get this to work you have to add an alias for the mixin fn to the class. I.e. something like this (hopefully the syntax is correct - I've never used alias much): mixin fnImpl!(int) mixFn; alias mixFn.fn fn;Oops! I just noticed that my previous example had an error--the return types were causing the errors. In any case, it seems like you understood my true problem anyway. After some experimentation, I managed to get it all working using something like the following: typedef int type1; // fake type for the example typedef int type2; // fake type for the example typedef int type3; // fake type for the example interface I { public: int fn( type1 ); int fn( type2 ); int fn( type3 ); } template T( SomeT ) { public: template fnImpl( OtherT ) { int fn( OtherT x ) { type2 y; return this.fn( y ); } } mixin fnImpl!(type1) fnImpl1; alias fnImpl1.fn fn; mixin fnImpl!(type2) fnImpl2; alias fnImpl2.fn fn; int fn( type3 x ) { return 0; } } class C : I { mixin T!(int); } Giving the mixins separate names and adding the alias line was what solved the problem. And putting everything in yet another mixin was closer to what I'm actually doing so it was nice to see that work as well. I must say, there are quite a few hurdles to jump in order to do what I'd consider typical template function overloading. But at least it's possible so I can't really complain. Thanks again for the help. Sean
Jun 16 2004