Dobry błąd kompilatora. W przypadku tego typu sprawdzeń zawsze wracam do kompilatora Comeau przed powrotem do standardu i sprawdzeniem.
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(); ^
Teraz, ponieważ został opublikowany przez innego użytkownika, faktem jest, że standard nie pozwala na definiowanie wirtualnych metod szablonowych. Uzasadnieniem jest to, że dla wszystkich metod wirtualnych wpis musi być zarezerwowany w vtable. Problem polega na tym, że metody szablonów zostaną zdefiniowane dopiero po ich utworzeniu (użyciu). Oznacza to, że vtable będzie miał inną liczbę elementów w każdej jednostce kompilacji, w zależności od tego, ile różnych wywołań do f() z różnych typów się zdarzyć. Następnie cholery będzie podniesiony ...
Jeśli to, co chcesz jest na matrycy funkcji na jednym ze swoich argumentów i jednego konkretnego wersja jest wirtualny (zauważ część argumentu) można to zrobić:
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"
}
Jeśli chcesz to uogólnić dla dowolnego typu, to masz pecha. Rozważmy inny rodzaj delegacji zamiast polimorfizmu (rozwiązaniem może być agregacja + delegacja). Więcej informacji na temat problemu może pomóc w określeniu rozwiązania.
Przyjemny komunikat o błędzie! Może po przesłaniu go do MS Connect, nawet jeśli twój kod nie jest "legalny", wiadomość powinna być lepsza. – Lucero
Nie wiem na pewno, więc nie uważam tego za prawdziwą odpowiedź, ale założę się, że nie jest to legalne, ponieważ vtable byłby inny w różnych jednostkach kompilacji, które nazywałyby funkcję z różnymi typy (lub w ogóle tego nie nazywały). – rmeador
gcc daje mnóstwo komunikatów o błędach, zaczynając od "testtemp.cpp: 4: błąd: jawna specjalizacja w zakresie przestrzeni nazw" struct A "" – veefu