digitalmars.D.learn - abstract function templates
- Nrgyzer (32/32) Dec 26 2010 Hey guys,
- Simen kjaeraas (6/7) Dec 26 2010 D currently does not support virtual template functions (and thus
- Nrgyzer (2/2) Dec 26 2010 Ah, okay - remove override is enough.
- Nrgyzer (10/10) Dec 26 2010 I just figured out that this doesn't work, when I use a array with
- Simen kjaeraas (6/16) Dec 26 2010 Yes indeed. This was what I meant by saying that template functions
- Andrej Mitrovic (13/16) Dec 26 2010 Does it really make sense for a class to have methods that accept any
- Simen kjaeraas (5/17) Dec 26 2010 Well, operator overloading comes to mind. Certainly for types that
- Jonathan M Davis (9/27) Dec 26 2010 In many cases, it would make sense to make virtual functions which have ...
- Simen kjaeraas (6/12) Dec 26 2010 I'm very aware of that. The only possibility I see would be to build
- Nrgyzer (16/16) Dec 26 2010 The sense is that I have different, drawable classes/object - for
- Andrej Mitrovic (23/23) Dec 26 2010 I think this is relevant:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (10/32) Dec 28 2010 Bar.draw does not override, but "hide" Foo.draw. They are unrelated
- bearophile (6/10) Dec 28 2010 But the error messages given by DMD 2.051 aren't easy to understand for ...
- Andrej Mitrovic (2/7) Dec 28 2010 Agreed. Can you file a bug report?
- bearophile (4/5) Dec 28 2010 Sorry, but I don't understand the topic enough yet (I don't know why tem...
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (7/8) Dec 28 2010 bug report to someone else that's able to write something meaningful in
- Simen kjaeraas (9/10) Dec 28 2010 First of all, they can. But it's a shitload of extra work, and requires
- Andrej Mitrovic (1/1) Dec 28 2010 Thanks, Ali! :)
Hey guys, I've the following class: abstract class Drawable { public { uint getHeight() { ... } uint getWidth() { ... } abstract { void draw(T = void*)(uint zPos, T obj = null); } } } When I compile this code, it compiles without any errors. Now... I have the following class: class Texture : Drawable { public { override { void draw(T = void*)(uint zPos, T obj = null) { ... } } } } When I create a new instance of Texture and try to call newInstance.draw(50), I always get the following error: "Error: variable Texture.draw!(void*).draw.this override cannot be applied to variable" "Error: variable Texture.draw!(void*).draw.zPos override cannot be applied to variable" "Error: variable Texture.draw!(void*).draw.pbo override cannot be applied to variable" "Error: variable ... Texture.draw!(void*).draw.zPos override cannot be applied to variable" I hope anyone can help me - thanks!
Dec 26 2010
Nrgyzer <nrgyzer gmail.com> wrote:I hope anyone can help me - thanks!D currently does not support virtual template functions (and thus overriding such). The solution (if you can call it that) is to simply not mark draw with override, and perhaps remove it from the base class. -- Simen
Dec 26 2010
I just figured out that this doesn't work, when I use a array with super class as base type, for example: Drawable[] textures; Then, I'll get the following error: "Error: function draw!(void*).draw non-virtual functions cannot be abstract". I just implemented the draw-function as empty function, which doesn't create any errors, but I seems that it's not calling the draw- function of any texture instance. It seems that it is always calling Drawable.draw() - the empty function. When I create a new instance of my Texture-class, it calls the draw-function of the texture-instance.
Dec 26 2010
Nrgyzer <nrgyzer gmail.com> wrote:I just figured out that this doesn't work, when I use a array with super class as base type, for example: Drawable[] textures; Then, I'll get the following error: "Error: function draw!(void*).draw non-virtual functions cannot be abstract". I just implemented the draw-function as empty function, which doesn't create any errors, but I seems that it's not calling the draw- function of any texture instance. It seems that it is always calling Drawable.draw() - the empty function. When I create a new instance of my Texture-class, it calls the draw-function of the texture-instance.Yes indeed. This was what I meant by saying that template functions cannot be virtual. D sadly has no way to create templated functions that work in a class hierarchy. :( -- Simen
Dec 26 2010
On 12/27/10, Simen kjaeraas <simen.kjaras gmail.com> wrote:Yes indeed. This was what I meant by saying that template functions cannot be virtual. D sadly has no way to create templated functions that work in a class hierarchy. :(Does it really make sense for a class to have methods that accept any type of argument? It's one thing to have a class specialized on some type(s), e.g.: class Foo(T1, T2) { void bar(T1 var, T2 etc) { } } But having a class method which can accept any type, that seems odd to me. I don't know since I've never used such a thing before, but maybe it has some good use cases? (I'd love to know about those btw!). You can introduce constraints, but I thought having parameterized classes would solve most of the use-case scenarios.
Dec 26 2010
Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:Does it really make sense for a class to have methods that accept any type of argument? It's one thing to have a class specialized on some type(s), e.g.: class Foo(T1, T2) { void bar(T1 var, T2 etc) { } } But having a class method which can accept any type, that seems odd to me. I don't know since I've never used such a thing before, but maybe it has some good use cases? (I'd love to know about those btw!).Well, operator overloading comes to mind. Certainly for types that would allow mathematical operations with any generic numeric type.You can introduce constraints, but I thought having parameterized classes would solve most of the use-case scenarios.-- Simen
Dec 26 2010
On Sunday 26 December 2010 16:18:19 Simen kjaeraas wrote:Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:In many cases, it would make sense to make virtual functions which have all of the types that make sense and then have a templated function called in each of them so that their implementation is still shared. A big problem with having template functions be virtual is the fact that such functions don't exist until they're called, whereas a class and its virtual function need to exist regardless of whether the functions get called - particularly when you bring libraries into it. - Jonathan M DavisDoes it really make sense for a class to have methods that accept any type of argument? It's one thing to have a class specialized on some type(s), e.g.: class Foo(T1, T2) { void bar(T1 var, T2 etc) { } } But having a class method which can accept any type, that seems odd to me. I don't know since I've never used such a thing before, but maybe it has some good use cases? (I'd love to know about those btw!).Well, operator overloading comes to mind. Certainly for types that would allow mathematical operations with any generic numeric type.
Dec 26 2010
Jonathan M Davis <jmdavisProg gmx.com> wrote:A big problem with having template functions be virtual is the fact that such functions don't exist until they're called, whereas a class and its virtual function need to exist regardless of whether the functions get called - particularly when you bring libraries into it.I'm very aware of that. The only possibility I see would be to build vtables at startup (sorta also possible at link-time), and I think we can all agree that's an uncomfortable nest of worms. -- Simen
Dec 26 2010
The sense is that I have different, drawable classes/object - for example a simple texture (not clickable) and a button (clickable). When the user clicks the mouse, the obj-param which is defined by using draw!(T = void*)(uint zPos, T obj = null) will be saved in a template-struct which should have the type of obj -> struct myStruct (T). The advantage is, that I can use the obj referenced in the struct without any casting. I just solved the problem by declaring draw() as final-function and used a new value as callback in the final draw()-function - for example: ... private void delegate() drawCallback; public final void draw(T = void*)(uint zPos, T obj = null) { drawCallback(); // ... do additional work }
Dec 26 2010
I think this is relevant: http://www.digitalmars.com/d/2.0/template.html : "Limitations": Templates cannot be used to add non-static members or virtual functions to classes. Templates cannot add functions to interfaces. But I'm a little confused as to how it all works out. This will work: import std.stdio; class Foo { void draw(T)(T t) { writeln("Foo"); }; } class Bar : Foo { /* override */ void draw(T)(T t) { writeln("Bar"); }; } void main() { Bar bar = new Bar(); bar.draw(1); // "Bar" (cast(Foo)bar).draw(1); // "Foo" } But uncomment the override and it fails. Experts will have to chime in on this one. :)
Dec 26 2010
Andrej Mitrovic wrote:I think this is relevant: http://www.digitalmars.com/d/2.0/template.html : "Limitations": Templates cannot be used to add non-static members or virtual functions to classes. Templates cannot add functions to interfaces. But I'm a little confused as to how it all works out. This will work: import std.stdio; class Foo { void draw(T)(T t) { writeln("Foo"); }; } class Bar : Foo { /* override */ void draw(T)(T t) { writeln("Bar"); }; }Bar.draw does not override, but "hide" Foo.draw. They are unrelated functions.void main() { Bar bar = new Bar(); bar.draw(1); // "Bar"Bar.draw!int is called. No virtual dispatch is involved, as Foo.draw!int doesn't even exist.(cast(Foo)bar).draw(1); // "Foo"Now Foo.draw!int is instantiated (at compile time) an is called. There is no Bar.draw!int instantiated at all.} But uncomment the override and it fails.That's because "Templates cannot be used to add [...] virtual functions to classes" Ali
Dec 28 2010
Ali Çehreli:> But uncomment the override and it fails. That's because "Templates cannot be used to add [...] virtual functions to classes"But the error messages given by DMD 2.051 aren't easy to understand for me: test.d(10): Error: variable test.Bar.draw!(int).draw.this override cannot be applied to variable test.d(10): Error: variable test.Bar.draw!(int).draw.t override cannot be applied to variable Bye, bearophile
Dec 28 2010
On 12/28/10, bearophile <bearophileHUGS lycos.com> wrote:But the error messages given by DMD 2.051 aren't easy to understand for me: test.d(10): Error: variable test.Bar.draw!(int).draw.this override cannot be applied to variable test.d(10): Error: variable test.Bar.draw!(int).draw.t override cannot be applied to variableAgreed. Can you file a bug report?
Dec 28 2010
Andrej Mitrovic:Agreed. Can you file a bug report?Sorry, but I don't understand the topic enough yet (I don't know why templated methods can't be virtual), so I leave the bug report to someone else that's able to write something meaningful in the bug report :-) Bye, bearophile
Dec 28 2010
bearophile wrote:(I don't know why templated methods can't be virtual), so I leave thebug report to someone else that's able to write something meaningful in the bug report :-) I created a bug report just about the compiler error message: http://d.puremagic.com/issues/show_bug.cgi?id=5387 I think the compiler rejects the code according to spec. Ali
Dec 28 2010
bearophile <bearophileHUGS lycos.com> wrote:(I don't know why templated methods can't be virtual)First of all, they can. But it's a shitload of extra work, and requires that compilation be mixed up with linking. Whenever a templated method is used from any subclass, it has to be generated for the base class, and any and all subclasses that override it. We can't know every subclass until link-time (not even then, given dynamic linking). -- Simen
Dec 28 2010