Jump to page: 1 2
Thread overview
abstract function templates
Dec 26, 2010
Nrgyzer
Dec 26, 2010
Simen kjaeraas
Dec 26, 2010
Nrgyzer
Dec 26, 2010
Nrgyzer
Dec 26, 2010
Simen kjaeraas
Dec 27, 2010
Andrej Mitrovic
Dec 27, 2010
Simen kjaeraas
Dec 27, 2010
Jonathan M Davis
Dec 27, 2010
Simen kjaeraas
Dec 27, 2010
Nrgyzer
Dec 26, 2010
Andrej Mitrovic
Dec 28, 2010
Ali Çehreli
Dec 28, 2010
bearophile
Dec 28, 2010
Andrej Mitrovic
Dec 28, 2010
bearophile
Dec 28, 2010
Ali Çehreli
Dec 28, 2010
Simen kjaeraas
Dec 28, 2010
Andrej Mitrovic
December 26, 2010
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!
December 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
December 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. :)
December 26, 2010
Ah, okay - remove override is enough.

Thanks :)
December 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.
December 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
December 27, 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.
December 27, 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
December 27, 2010
On Sunday 26 December 2010 16:18:19 Simen kjaeraas wrote:
> 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.

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 Davis
December 27, 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
« First   ‹ Prev
1 2