Templates and virtual functions

Aarti_pl aarti at interia.pl
Thu Jan 22 00:04:57 PST 2009


Walter Bright pisze:
> Setting aside the technical issues for the moment, I'd like to go back 
> to the notion that structs are for compile time polymorphism and classes 
> are for runtime polymorphism. Template functions are clearly in the 
> compile time camp, and if you need compile time polymorphism in a class, 
> perhaps the design should be seriously looked at to see if that's 
> justifiable.

That's not always true. I have similar case in my serialization library 
(Doost project) where template function is called in class to get 
information about class properties/values. Then, to support 
serialization from base classes I need to make virtual call to get most 
derived class. My point here is that there are cases where virtual 
template functions would be needed in classes.


> As to resolving the technical issue, put the instantiation of the 
> template inside another virtual function:
> 
> class foo {
>     T nothing(T)(T arg) {  // Non-virtual.
>         return arg;
>     }
> 
>     int virtual_nothing(int arg)
>     {
>     return nothing!(arg);
>     }
> 
>     float virtual_nothing(float arg)
>     {
>     return nothing!(arg);
>     }
> }
> 
> The advantage of this is there is nothing new to learn.

I was thinking about above design in my serialization library. As I 
already said it is needed for serialization of classes from base class 
reference (It's necessary to know most derived class to do proper 
serialization).

Unfortunately such a design cause quite a big problem for users of such 
a library. Please let me explain below.

I have following template in my libs:

template Serializable() {
   void describeUdt(T)(T arch) {
     foreach(i, v; this.tupleof)
       arch.describe(this.tupleof[i], this.tupleof[i].stringof);
   }
}

Argument passed to function describeUdt is Archive, which is class, 
representing what type of output/input is used for serialization (JSon, 
Text, Binary etc....)

To make user class serializable is is just enough to put it as a mixin 
into user class.

class UserClassA {
   mixin Serializable;
}

And now, to support serialization from base class pointer I played with 
following design:


class UserClassA {
   mixin Serializable;

   void transportUdt(Archive arch) {
     describeUdt!(Archive)(arch);
   }
}

class UserClassB : UserClassA {
   mixin Serializable;

   void transportUdt(Archive arch) {
     describeUdt!(Archive)(arch);
   }
}

The problem here is that:
1. User of library will have to know all types of Archive template class 
(which is privately created by Serializer class). There are a lot of 
different possible classes which can be produced from Archive template 
class based on input/output stream type and based on type of archive. 
They should be unknown for user.

2. It is necessary to put functions transportUdt for every different 
Archive type into serialized class. It must be done by hand by user, as 
I don't see a way to make it automatically...

Do you see any nice solution for above problem? I was thinking about 
registering somehow different Archive types during their instantiations 
and then automatically generating necessary functions transportUdt, but 
it doesn't seem to be possible currently...

I would be happy to know about a good solution for this...

REF: 
http://www.dsource.org/projects/doost/browser/trunk/doost/util/serializer

Best Regards
Marcin Kuszczak
(aarti_pl)
www.zapytajmnie.com - my christian site



More information about the Digitalmars-d mailing list