digitalmars.D.learn - Template Inheritance
- %u (13/13) Feb 18 2012 I've been working on porting an old D library to D2, and I'm running int...
- %u (3/3) Feb 18 2012 In the interim, I'm just redefining the template in the base class, but ...
- %u (1/1) Feb 18 2012 Correction: redefining in the *subclass*. Silly me.
- Jonathan M Davis (5/23) Feb 18 2012 Template functions are non-virtual. You can't derive from them. If you w...
- %u (7/7) Feb 18 2012 Thanks! I guess I'll just have to live with redefining the functions, do...
- %u (8/8) Feb 18 2012 I think I got it! This seems to work:
- Jonathan M Davis (3/13) Feb 18 2012 That seems like it could work.
- Timon Gehr (7/15) Feb 18 2012 This kills IFTI for the base class templates. It would be nice if it
- BLM (11/11) Feb 21 2012 That last one looks a lot better than my solution. It's certainly a lot ...
- Timon Gehr (3/14) Feb 25 2012 You can post it in the bug tracker and choose severity as 'enhancement':
- Jonathan M Davis (9/18) Feb 18 2012 aliases only work with actual, concrete functions. So, you could alias a...
- Jacob Carlborg (4/27) Feb 19 2012 Yeah, but isn't that an overload, or specialization, in the subclass?
- Jonathan M Davis (7/15) Feb 19 2012 Yes. But if you're trying to give the function different behavior in the...
- Timon Gehr (3/17) Feb 18 2012 There seems to be no perfect way in the current implementation.
I've been working on porting an old D library to D2, and I'm running into a nasty issue with templates and inheritance. I've got a base class like this: class Reader { void get(T)(ref T[] buffer); } and a subclass like this: class SubReader { void get()(SomeClass param); } The problem is that by creating a new form of the template in the subclass, I made the base class's version invisible. If I try to use "alias Reader.get get" like I would do for functions, the compiler complains that the symbols clash (no musical puns intended). Does anyone know how to get this to work?
Feb 18 2012
In the interim, I'm just redefining the template in the base class, but that's a really annoying hack to have to perform every single time I have to make a new form of the template.
Feb 18 2012
On Sunday, February 19, 2012 00:55:59 %u wrote:I've been working on porting an old D library to D2, and I'm running into a nasty issue with templates and inheritance. I've got a base class like this: class Reader { void get(T)(ref T[] buffer); } and a subclass like this: class SubReader { void get()(SomeClass param); } The problem is that by creating a new form of the template in the subclass, I made the base class's version invisible. If I try to use "alias Reader.get get" like I would do for functions, the compiler complains that the symbols clash (no musical puns intended). Does anyone know how to get this to work?Template functions are non-virtual. You can't derive from them. If you want the derived classes to have the same functions, you must redefine them in the derived class. - Jonathan M Davis
Feb 18 2012
Thanks! I guess I'll just have to live with redefining the functions, do some sort of interface/mixin thing, or change the class interface. It makes sense that template functions aren't virtual (how are you supposed to deal with vtables?), but I wish that at least an alias declaration could work. Maybe if there were some way to alias the base template and then modify it... Templates inheriting from templates would be a very interesting way to accomplish that, but it would be a very strange system...
Feb 18 2012
I think I got it! This seems to work: class Derived { //Pulls in all the template forms in the base class template get(args ...) { alias Base.get!args get; } //Create new versions of get() here. }
Feb 18 2012
On Sunday, February 19, 2012 01:23:13 %u wrote:I think I got it! This seems to work: class Derived { //Pulls in all the template forms in the base class template get(args ...) { alias Base.get!args get; } //Create new versions of get() here. }That seems like it could work. - Jonathan M Davis
Feb 18 2012
On 02/19/2012 02:23 AM, %u wrote:I think I got it! This seems to work: class Derived { //Pulls in all the template forms in the base class template get(args ...) { alias Base.get!args get; } //Create new versions of get() here. }This kills IFTI for the base class templates. It would be nice if it would work. Do you want to file an enhancement request? Otherwise I'll do it. This one lets you keep IFTI, but does not forward perfectly for some special implicit conversions. auto get(T...)(T a){return super.get!T(a);}
Feb 18 2012
That last one looks a lot better than my solution. It's certainly a lot clearer. One problem I discovered with using templates was that I ended up needing virtual functions, which means that I had to convert the template functions to mixins and just instantiate them for each type (at least there were only two types to handle!) in the base class. The problem I've got now is that if I create versions of get() that take different types in subclasses, I lose access to the superclass's overload set. If I try to use "alias Base.get get", DMD complains that the alias and the functions conflict. It looks like I can override existing overloads but not create new ones. I guess I might have to put a hold on the project until the language gets modified (assuming that actually happens). How would I go about filing an enhancement request?
Feb 21 2012
On 02/22/2012 01:13 AM, BLM wrote:That last one looks a lot better than my solution. It's certainly a lot clearer. One problem I discovered with using templates was that I ended up needing virtual functions, which means that I had to convert the template functions to mixins and just instantiate them for each type (at least there were only two types to handle!) in the base class. The problem I've got now is that if I create versions of get() that take different types in subclasses, I lose access to the superclass's overload set. If I try to use "alias Base.get get", DMD complains that the alias and the functions conflict. It looks like I can override existing overloads but not create new ones. I guess I might have to put a hold on the project until the language gets modified (assuming that actually happens). How would I go about filing an enhancement request?You can post it in the bug tracker and choose severity as 'enhancement': http://d.puremagic.com/issues/
Feb 25 2012
On Sunday, February 19, 2012 01:17:42 %u wrote:Thanks! I guess I'll just have to live with redefining the functions, do some sort of interface/mixin thing, or change the class interface. It makes sense that template functions aren't virtual (how are you supposed to deal with vtables?), but I wish that at least an alias declaration could work. Maybe if there were some way to alias the base template and then modify it... Templates inheriting from templates would be a very interesting way to accomplish that, but it would be a very strange system...aliases only work with actual, concrete functions. So, you could alias an specific instantiation of a templated function, but not the templated function as a whole. e.g. alias get!int getInt; works, but alias get getVal; doesn't. - Jonathan M Davis
Feb 18 2012
On 2012-02-19 02:07, Jonathan M Davis wrote:On Sunday, February 19, 2012 00:55:59 %u wrote:Yeah, but isn't that an overload, or specialization, in the subclass? -- /Jacob CarlborgI've been working on porting an old D library to D2, and I'm running into a nasty issue with templates and inheritance. I've got a base class like this: class Reader { void get(T)(ref T[] buffer); } and a subclass like this: class SubReader { void get()(SomeClass param); } The problem is that by creating a new form of the template in the subclass, I made the base class's version invisible. If I try to use "alias Reader.get get" like I would do for functions, the compiler complains that the symbols clash (no musical puns intended). Does anyone know how to get this to work?Template functions are non-virtual. You can't derive from them. If you want the derived classes to have the same functions, you must redefine them in the derived class. - Jonathan M Davis
Feb 19 2012
On Sunday, February 19, 2012 12:34:07 Jacob Carlborg wrote:Yes. But if you're trying to give the function different behavior in the derived class, what else can you do? Of course, it won't work with polymorphism though (the version that gets called will depend on the reference that you're using), so it may not be such a good idea from that standpoint. Really, templated functions and class hierarchies don't get along very well. - Jonathan M DavisTemplate functions are non-virtual. You can't derive from them. If you want the derived classes to have the same functions, you must redefine them in the derived class. - Jonathan M DavisYeah, but isn't that an overload, or specialization, in the subclass?
Feb 19 2012
On 02/19/2012 01:55 AM, %u wrote:I've been working on porting an old D library to D2, and I'm running into a nasty issue with templates and inheritance. I've got a base class like this: class Reader { void get(T)(ref T[] buffer); } and a subclass like this: class SubReader { void get()(SomeClass param); } The problem is that by creating a new form of the template in the subclass, I made the base class's version invisible. If I try to use "alias Reader.get get" like I would do for functions, the compiler complains that the symbols clash (no musical puns intended).That is a bug.Does anyone know how to get this to work?There seems to be no perfect way in the current implementation.
Feb 18 2012