templates may not be ‘virtual’

Javier picture Javier · Feb 10, 2011 · Viewed 16.2k times · Source

Given the code below, the compiler is showing a message pointing that error: templates may not be ‘virtual’. Does anyone have a suggestion on how to solve the bug?

template < class FOO_TYPE>
class CFoo{
    public:
        ...
        template < class BAR_TYPE >
        virtual void doSomething( const CBar<BAR_TYPE> &); // here's the error
        ...
        virtual ~CFoo();
    protected:
        MyClass < FOO_TYPE > * m_pClass;
};

template < class FOO_TYPE >
template < class BAR_TYPE >
void CFoo<FOO_TYPE>::doSomething( const CBar<BAR_TYPE> & refBar ){
    ...
}

Answer

MSalters picture MSalters · Feb 11, 2011

The easiest reason to see why this is illegal is by considering the vtable. Sure, that's just one common implementation, and others are allowed. But all virtual functions in C++ are designed such that they can be implemented with a vtable.

Now, how many entries are there in the vtable of CFoo<int> ? Is there an entry for doSomething<float> ? And doSomething<float*>? And doSomething<float**> ? Templates such as these allow an infinite set of functions to be generated. Usually that's no problem, as you use only a finite subset, but for virtual functions this subset isn't known, and therefore the vtable would need to be infinite.

Now, it's possible that you really wanted only a single entry in the vtable. In that case, you'd write it as follows:

template < class FOO_TYPE, class BAR_TYPE>
class CFoo{
    public:
        ...
        virtual void doSomething( const CBar<BAR_TYPE> &); // now OK.
        ...
        virtual ~CFoo();
    protected:
        MyClass < FOO_TYPE > * m_pClass;
};

This means that the vtable for CFoo<int, float> will have one entry, for doSomething(float const&).