2014-07-23 4 views
5

Der folgende Code ++ 2013 in Visual C kompiliert, aber nicht unter G ++ 4.8.2:Verarbeitung von instanziierte Template-Funktionen

template<class T> 
int MyFunc(T& t) 
{ 
    return static_cast<int>(CCodes::blah); 
} 

template<> 
int MyFunc(float& t) 
{ 
    return 0; 
} 

int main() { 
    float f = 10.f; 
    return MyFunc(f); 
} 

Visual C++ scheint die allgemeine Template-Funktion zu ignorieren, weil nur die Spezialisierung MyFunc<float> verwendet wird. G ++ analysiert die allgemeine Funktion trotzdem und erkennt, dass die CCodes-Enumeration nicht definiert wurde.

Welches ist richtig? Oder ist diese Implementierung definiert?

+0

In beiden Fällen ist fehlerhafter Code immer noch fehlerhafter Code. –

+0

Also ich denke, meine Frage könnte umformuliert werden: Ist das falsch Code? Oder ist es dem Compiler erlaubt, uninstantiierte Template-Definitionen nicht zu parsen? – Tom

+0

@Tom Was passiert, wenn Sie 'return static_cast (CCodes :: blah);'? –

Antwort

6

GCC ist korrekt, und jeder andere Compiler außer MSVC wird das gleiche tun.

Dies ist ein großer Fehler, der tatsächlich auf einer Roadmap von MSVC auftrat. Es war in der Kategorie "ferne Zukunft". Sie müssen ihre Vorlagen-Engine neu schreiben, um sie zu reparieren.

Es gibt eine Argumentation, dass die Diagnose einer schlecht geformten Vorlage optional ist, da es sich um eine Vorlage ohne wohlgeformte Instanziierung handelt, die nicht markiert werden muss.

  1. Der Standard erfordert, dass die Vorlage analysiert wird, und Fehler bei der Analyse müssen unabhängig von der Instanziierung diagnostiziert werden.
  2. Jeder andere Compiler führt die Diagnose durch, so dass MSVC-Benutzer in Wirklichkeit keinen unportablen Code erstellen. Sich beschweren ist eine wirklich gute Idee, auch wenn es nicht erforderlich ist.
+0

Hmm, §14.6 [temp.res]/p10 sagt "Wenn ein Name nicht von einem Template-Parameter (wie in 14.6.2 definiert) abhängt, muss eine Deklaration (oder eine Menge von Deklarationen) für diesen Namen im Bereich um sein der Punkt, an dem der Name in der Vorlagendefinition erscheint ". Im Gegensatz zur allgemeinen Regel "keine gültige Spezialisierung" ist hier keine "keine Diagnose erforderlich". –

+0

@ T.C. Recht. Da C++ eine kontextsensitive (nicht kontextfreie) Grammatik ist, muss die Namenssuche als Teil des Parsens durchgeführt werden. Dies ist ein Teil dessen, was ich mit (1) meinte. – Potatoswatter

+0

Eigentlich ist die Situation etwas schlimmer als das - Sie können buchstäblich fast jeden Müll in den Körper einer uninstantiated Template-Funktion und der VC++ - Compiler wird es ignorieren. Solange es die schließende Klammer nicht enthält und den Präprozessor nicht stört, scheint es egal zu sein. – Tom

Verwandte Themen