Хорошая ошибка компилятора. Для этого типа проверок я всегда возвращаюсь к компилятору Comeau , прежде чем вернуться к стандарту и проверке.
Comeau C / C ++ 4.3.10.1 (6 октября 2008 г.)
11:28:09) для ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing.
Все права защищены. MODE: строгий
ошибки C ++ C ++ 0x_extensions
"ComeauTest.c", строка 3: ошибка:
«виртуальный» не допускается в функции
шаблон
декларация
шаблон виртуальной пустоты f ();
^
"ComeauTest.c", строка 10: ошибка:
«виртуальный» не допускается в функции
шаблон
декларация
шаблон виртуальной пустоты f ();
^
Теперь, поскольку это было опубликовано другим пользователем, факт в том, что стандарт не позволяет вам определять виртуальные шаблонные методы. Обоснование заключается в том, что для всех виртуальных методов запись должна быть зарезервирована в виртуальной таблице. Проблема в том, что методы шаблона будут определены только тогда, когда они были созданы (использованы). Это означает, что vtable будет иметь разное количество элементов в каждом модуле компиляции, в зависимости от того, сколько разных вызовов f () с разными типами происходит. Тогда ад восстанет ...
Если вам нужна шаблонная функция с одним из ее аргументов, а одна конкретная версия является виртуальной (обратите внимание на часть аргумента), вы можете сделать это:
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 ); // The compiler will prefer the non-templated method and print "derived"
}
Если вы хотите, чтобы это обобщалось для любого типа, то вам не повезло. Рассмотрим другой тип делегирования вместо полиморфизма (агрегация + делегирование могут быть решением). Дополнительная информация о рассматриваемой проблеме поможет найти решение.