I heard, templated member functions of a class can't be virtual. Is it true? BTW, if they can be, then please give an example of such a scenario when I would need such function?
Think about it for a while:
Q.1. How could you make a templated virtual function?
Q.2. What's its signature?
Q.3. How many vtable entries do you reserve?
Q.4. How would you distinguish between an override/hide and an overload?
Hope that helps.
Templates are all about the compiler generating code at compile-time. Virtual functions are all about the run-time system figuring out which function to call at run-time.
Once the run-time system figured out it would need to call a templatized virtual function, compilation is all done and the compiler cannot generate the appropriate instance anymore. Therefor, you cannot have virtual member function templates.
However, there are a few powerful and interesting techniques stemming from combining polymorphism and templates, notably so-called type erasure.
C++ doesn't allow virtual template member functions right now. The most likely reason is the complexity of implementing it. Rajendra gives good reason why it can't be done right now but it could be possible with reasonable changes of the standard. Especially working out how many instantiations of a templated function actually exist and building up the vtable seems difficult if you consider the place of the virtual function call. Standards people just have a lot of other things to do right now and C++1x is a lot of work for the compiler writers as well.
When would you need a templated member function? I once came across such a situation where I tried to refactor a hierarchy with a pure virtual base class. It was a poor style for implementing different strategies. I wanted to change the argument of one of the virtual functions to a numeric type and instead of overloading the member function and override every overload in all sub-classes I tried to use virtual template functions (and had to find out they don't exist.)
The following code can be compiled and runs properly, using MinGW G++ 3.4.5 on Window 7:
#include <iostream>
#include <string>
using namespace std;
template <typename T>
class A{
public:
virtual void func1(const T& p)
{
cout<<"A:"<<p<<endl;
}
};
template <typename T>
class B
: public A<T>
{
public:
virtual void func1(const T& p)
{
cout<<"A<--B:"<<p<<endl;
}
};
int main(int argc, char** argv)
{
A<string> a;
B<int> b;
B<string> c;
A<string>* p = &a;
p->func1("A<string> a");
p = dynamic_cast<A<string>*>(&c);
p->func1("B<string> c");
B<int>* q = &b;
q->func1(3);
}
and the output is:
A:A<string> a
A<--B:B<string> c
A<--B:3
And later I added a new class X:
class X
{
public:
template <typename T>
virtual void func2(const T& p)
{
cout<<"C:"<<p<<endl;
}
};
When I tried to use class X in main() like this:
X x;
x.func2<string>("X x");
g++ report the following error:
vtempl.cpp:34: error: invalid use of `virtual' in template declaration of `virtu
al void X::func2(const T&)'
So it is obvious that:
- virtual member function can be used in a class template. It is easy for compiler to construct vtable
- It is impossible to define a class template member function as virtual, as you can see, it hard to determine function signature and allocate vtable entries.