Macht eine Funktion Vorlage Spezialisierung virtuelle legal?
-
09-09-2019 - |
Frage
In C ++, eine Funktion Vorlage Spezialisierung sollte genau wie eine normale Funktion handeln. Heißt das, dass ich eine virtuelle machen?
Zum Beispiel:
struct A
{
template <class T> void f();
template <> virtual void f<int>() {}
};
struct B : A
{
template <class T> void f();
template <> virtual void f<int>() {}
};
int main(int argc, char* argv[])
{
B b;
A& a = b;
a.f<int>();
}
Visual Studio 2005 gibt mir die folgende Fehlermeldung:
schwerwiegender Fehler C1001:. Ein interner Fehler in dem Compiler aufgetreten
Lösung
Nizza Compiler-Fehler. Für diese Art von Kontrollen Rückfall habe ich immer auf die Comeau Compiler vor dem Standard und Kontrolle zurück.
Comeau C / C ++ 4.3.10.1 (6. Oktober 2008 11.28.09) für ONLINE_EVALUATION_BETA2 Copyright 1988-2008 Comeau Computing. Alle Rechte vorbehalten. MODE: strenge Fehler C ++ C ++ 0x_extensions
"ComeauTest.c", Zeile 3: Fehler: „Virtuelle“ ist nicht in einer Funktion erlaubt Vorlage Erklärung Vorlage virtual void f (); ^
"ComeauTest.c", Zeile 10: error: „Virtuelle“ ist nicht in einer Funktion erlaubt Vorlage Erklärung Vorlage virtual void f (); ^
Jetzt, da sie von einem anderen Benutzer geschrieben wurden, ist die Tatsache, dass der Standard nicht zulässt, dass virtuelle Templat Methoden definieren. Der Grund dafür ist, dass für alle virtuellen Methoden, muss ein Eintrag in der VTable reserviert werden. Das Problem ist, dass Template-Methoden werden nur dann definiert werden, wenn sie instanziiert wurden (gebraucht). Dies bedeutet, dass die V-Tabelle würde am Ende eine unterschiedliche Anzahl von Elementen in jeder Übersetzungseinheit, je nachdem, wie viele verschiedenen Anrufe f () mit verschiedenen Arten geschehen. Dann würde die Hölle angehoben werden ...
Wenn das, was Sie wollen eine Templat-Funktion auf einer seiner Argumente ist und eine bestimmte Version virtuell ist (man beachte den Teil des Arguments) Sie können es tun:
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"
}
Wenn Sie dies für jede Art generali wollen, dann sind Sie kein Glück. Betrachten wir eine andere Art von Delegation statt Polymorphismus (Aggregation + Delegation könnte eine Lösung sein). Weitere Informationen über das Problem bei der Hand bei der Bestimmung einer Lösung helfen würde.
Andere Tipps
Nach http://www.kuzbass.ru:8086/docs /isocpp/template.html ISO / IEC 14882: 1998:
-3- Ein Mitglied Funktionsvorlage ist nicht virtuell sein.
Beispiel:
template <class T> struct AA {
template <class C> virtual void g(C); // Error
virtual void f(); // OK
};
Wie andere haben darauf hingewiesen, dies ist nicht legal Code, weil ein Mitglied Funktionsvorlage nicht virtual
erklärt werden kann.
Doch auch Visual Studio 2012 Drossel auf diese: Klicken Sie hier für volle Größe
Ereignisprotokolle zeigen, dass der Compiler auf 0xC0000005
abgestürzt oder STATUS_ACCESS_VIOLATION
. Es ist schon komisch, wie ein bestimmtes (illegal) Code-Konstrukt kann den Compiler segfault machen ...