Nice compiler error. For this type of checks I always fallback to Comeau compiler before going back to the Standard and checking.
Comeau C/C++ 4.3.10.1 (Oct 6 2008
11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing.
All rights reserved. MODE:strict
errors C++ C++0x_extensions
"ComeauTest.c", line 3: error:
"virtual" is not allowed in a function
template
declaration
template virtual void f();
^
"ComeauTest.c", line 10: error:
"virtual" is not allowed in a function
template
declaration
template virtual void f();
^
Now, as it has been posted by other user, the fact is that the standard does not allow you to define virtual templated methods. The rationale is that for all virtual methods, an entry must be reserved in the vtable. The problem is that template methods will only be defined when they have been instantiated (used). This means that the vtable would end up having a different number of elements in each compilation unit, depending on how many different calls to f() with different types happen. Then hell would be raised...
If what you want is a templated function on one of its arguments and one specific version being virtual (note the part of the argument) you can do it:
class Base
{
public:
template <typename T> void f( T a ) {}
virtual void f( int a ) { std::cout << "base" << std::endl; }
};
class Derived : public Base
{
public:
virtual void f( int a ) { std::cout << "derived" << std::endl; }
};
int main()
{
Derived d;
Base& b = d;
b.f( 5 ); // compiler will prefer the non-templated method and print "derived"
}
If you want this generalized for any type, then you are out of luck. Consider other type of delegation instead of polymorphism (aggregation + delegation could be a solution). More info on the problem at hand would help in determining a solution.