virtual functions and templates

S

SainTiss

Hi,

Is there an extra overhead in using virtual functions and templates?
Or is is just the same overhead as with regular classes?

Either way, if you'd want to avoid it, will you always end up
with code duplication?

For example: let's say you've got two template specializations, which
differ only slightly... So you put the common behaviour in a
base class...
This is fine, but if a "common" method needs to call a "specialized" one,
it seems to me you're always going to need polymorphism...

The only way around seems to be not creating the base class, and
just copying the whole class to specialize it...

Is there a third possibility without the disadvantages of these two?

Thanks,

Hans
 
T

tom_usenet

Hi,

Is there an extra overhead in using virtual functions and templates?

Sort of - each instantiation will get its own vtable and RTTI, etc.,
and this can lead to quite a lot of code bloat when there are a large
number of different instantiations of the template.
Or is is just the same overhead as with regular classes?

Well, it is the same overhead as if you wrote all of the equivalent
non-template code. e.g.

class foo_int
{ //...
};

class foo_double
{ //...
};

etc.
Either way, if you'd want to avoid it, will you always end up
with code duplication?

No, there are techniques to avoid code duplication, the "curiously
recurring template pattern" being one. Some form of parametrised
inheritence is the key, anyway.
For example: let's say you've got two template specializations, which
differ only slightly... So you put the common behaviour in a
base class...
This is fine, but if a "common" method needs to call a "specialized" one,
it seems to me you're always going to need polymorphism...

Yes, but you can use compile-time polymorphism. e.g.

template <class Derived>
class CommonStuff
{
// non-virtual functions, casting this
// to a Derived* if necessary
};

template <class T>
class MyDerived: public CommonStuff<MyDerived<T> >
{
//add/change whatever you like
};

template<>
class MyDerived<int>: public CommonStuff<MyDerived<int> >
{
//add whatever you like
};

//and even
class Special: public CommonStuff<Special>
{
//...
};

Another alternative:

template <class T>
class CommonStuff
{
// non-virtual functions, casting this
// to a Derived* if necessary
};

template <class T>
class MyDerived: public CommonStuff<T>
{
//add/change whatever you like
};

//CommonStuff<int> not specialised
template<>
class MyDerived<int>: public CommonStuff<int>
{
//add whatever you like
};
The only way around seems to be not creating the base class, and
just copying the whole class to specialize it...

Avoid this if possible - it's a maintainance nightmare.
Is there a third possibility without the disadvantages of these two?

One of the above might be suitable.

Tom
 
S

SainTiss

tom_usenet said:
Another alternative:

template <class T>
class CommonStuff
{
// non-virtual functions, casting this
// to a Derived* if necessary
};

template <class T>
class MyDerived: public CommonStuff<T>
{
//add/change whatever you like
};

//CommonStuff<int> not specialised
template<>
class MyDerived<int>: public CommonStuff<int>
{
//add whatever you like
};

I think I get the first alternative, but this one puzzles me a bit... How
can the CommonStuff class cast to a Derived* if it doesn't know Derived? It
only knows T from what I can see...

So how exactly is this supposed to work then?

Thanks,

Hans
 
T

tom_usenet

I think I get the first alternative, but this one puzzles me a bit... How
can the CommonStuff class cast to a Derived* if it doesn't know Derived? It
only knows T from what I can see...

So how exactly is this supposed to work then?

Copy and paste error - ignore that comment!

Tom
 
S

SainTiss

tom_usenet said:
Copy and paste error - ignore that comment!

Tom

Ok, but ignoring that comment, I don't really see how this is alternative is
going to avoid polymorphism? How can the CommonStuff class call a
specialized method if it doesn't know about the Derived class and can't use
polymorphism?

Thanks,

Hans
 
T

tom_usenet

Ok, but ignoring that comment, I don't really see how this is alternative is
going to avoid polymorphism? How can the CommonStuff class call a
specialized method if it doesn't know about the Derived class and can't use
polymorphism?

It does know about the derived class if there is only one derived
class:

template <class T>
struct Derived;

template <class T>
struct Base
{
int f()
{
return static_cast<Derived<T>*>(this)->g() + 1;
}
};

template <class T>
struct Derived: public Base<T>
{
int g()
{
return 10;
}
};

template <>
struct Derived<int> : public Base<int>
{
int g()
{
return 3000;
}
};

#include <iostream>

int main()
{
Derived<double> d;
std::cout << d.f() << '\n';
Derived<int> i;
std::cout << i.f() << '\n';
}

The more general solution (for multiple derived classes) is the other
one I presented.

Tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,146
Messages
2,570,832
Members
47,374
Latest member
anuragag27

Latest Threads

Top