Re: r H2 deduce deduce template argument of a template class
inheriting from a non template base?
On 7 Mrz., 09:28, nguillot <nicolas.guil...@gmail.com> wrote:
I don't think I want the virtual function you spoke about.
I think you do. Though, I'm not sure what you're really trying to do.
It's a good idea, but I really want to receive a SData* as a parameter
in a function, or a method class:
this function or method will display for instance a dataGrid with a
cell dedicated for int in case of SDataContainer<int>, or a cell
dedicated to sting in case of SDataContainer<string>... and so on.
And another object would print those data in a html file for
instance... So I can't use an overridden virtual method: the
SDataContainer doesn't know how to print itself.
You have to think about what common operations an object of the type
SDate should support. This could be a conversion to a string, for
example. This conversion could be a virtual function that makes SData
an abstract base class.
struct SData
{
virtual ~SData() {}
virtual string to_string() const = 0;
};
However indeed it seems I've got a design problem.
Maybe I could use the class inheritance like that in order to avoid
the dynamic_cast in the displayer object.
SData
/\
|| (public inheritance)
SDataContainer<T>
/\
|| (private inheritance)
HtmlDataDisplay<T> or GridDataDisplay<T>
and in HtmlDataDisplay<T> or GridDataDisplay<T> I would override the
virtual "print_on" of SData base class. But I would specialize those
class for each type (int, bool...) needed to be handled.
I don't think that's a good idea. This can only work if you know in
advance what kind of "print_on" behaviour you want. Also, when you
have a pointer do an SData object you really don't know what it's
going to do when you call print_on. Does it print a grid or HTML code?
So, not only the actual type is abstracted but also how your data is
printed. Is this what you want??
You said:> (1) Specializing function templates is discouraged.
But if I don't use template specialization, I'll have to store the
data type in a way like that:
struct SData
{
enum eType
{
tBool,
tInt,
...
};
};
If you use templates and/or overloading for this the compiler can only
select the function according to the STATIC type. This is often not
what you want. If you pass a pointer of type SData* around (static
type) you can't expect the compiler to macigally select a function
based on the derived runtime type. This is what virtual functions are
for!
And store the data as a string inside SData, or inherit several
objects from SData: SDataBool, SDataInt and so on.
Here the template design is clearly more suitable.
As a rule of thumb: If you feel the need for something like this:
enum eType
{
tBool,
tInt,
...
};
it's very likely that a design with virtual functions is the better
one. The big disadvantage of your approach is that you have to check
the value of your eType variable possibly in many many places of your
code. This is a maintenance nightmare.
If you want dynamic polymorphism you can work with virtual functions
and to some extend with the typeid operator, though don't overuse the
typeid operator. Try to avoid it. I only used it once and threw it
away after a redesign.
Cheers!
SG