2010-11-28 10 views
41

den folgenden Code Gegeben:Mitglied Vorlage in lokaler Klasse

void f() 
{ 
    class A 
    { 
     template <typename T> 
     void g() {} 
    }; 
} 

g ++ 4.4 (und auch g++-4.6 -std=gnu++0x) klagt: "ungültige Erklärung der Mitgliedsvorlage in lokaler Klasse".

Offenbar dürfen lokale Klassen keine Template-Member haben. Was ist der Zweck dieser Beschränkung? Wird es in C++ 0x entfernt?

Hinweis: Wenn ich die lokale Klasse selbst eine Vorlage machen, anstatt ihm eine Vorlage Mitglied geben:

void f() 
{ 
    template <typename T>   
    class A 
    { 
     void g() {} 
    }; 
} 

erhalte ich „Fehler: eine Template-Deklaration im Block Umfang erscheint nicht“.

+1

Ich stieß auf diese alte Frage, während ich mit g ++ - 4.6 kämpfte. Es beschwert sich immer noch, also habe ich die Frage etwas bearbeitet. Hoffentlich bekommen wir mehr Antworten! –

+0

@AaronMcDaid: Leider gibt es zu diesem Zeitpunkt nicht viel mehr zu sagen. Wie litb in seinem Kommentar zu Crazy Eddies Antwort darauf hinwies, fügte C++ 11 ** nicht ** Unterstützung für lokale Klassen hinzu, die Templates sind oder Template-Member haben (Unterstützung für die Verwendung lokaler Klassen als Template-Parameter zu einem anderen (nichtlokalen) Klasse, aber das ist ein anderes Merkmal). Daher wird erwartet, dass g ++ dies in naher Zukunft nicht unterstützt, außer vielleicht als Compiler-Erweiterung. Ich denke, es ist eine Schande, weil es ein nützliches Feature gewesen wäre, aber hey, es gibt immer C++ 24 ... – HighCommander4

+0

C++ 14 erlaubt generische lambdas lokal mit variadischen Argumenten definiert zu werden. Diese sind sehr nah an Templates und können daher eine geeignete Problemumgehung sein. –

Antwort

9

Der Zweck dieser Einschränkung? Nur eine Vermutung, aber:

  • Sie können die Vorlage Klasse/Vorlage Mitglied Funktion nur innerhalb der umschließenden Funktion verwenden. Daher kennen Sie bereits alle verwendeten Typen innerhalb der Funktion und können somit direkt die verwendeten Typen angeben (bei verschiedenen Typen hätte die Template-Variante natürlich etwas Typisierung eingespart).
  • obwohl es nicht so scheint, ist es Arbeit für alle Compiler-Ersteller und Platz für Bugs und so muss es die Mühe wert sein.
  • Fun Fact: Versuchen Sie eine lokale Klasse innerhalb einer Funktion als Rückgabetyp für eine (C++ 0x) -Lambda-Funktion in der Funktion erklärt: MSVC 2010: interner Compiler Fehler ^^.

    +3

    Sie kennen vielleicht die verwendeten Typen, aber es verhindert immer noch die Verwendung von SFINAE-Tricks, ohne die Hilfsstrukturen zu offenbaren. – riv

    +2

    Wenn die lokale Klasse ein Besucher ist, der mit boost :: apply_visitor in einer boost :: variant verwendet wird, kennt man den Typ nicht. – Giel

    +0

    Noch kennen Sie die beteiligten Typen, wenn die Funktion selbst eine Vorlage ist. Diese Einschränkung macht es wahrscheinlich für Compilerautoren einfacher, obwohl ich nicht verstehe warum. Sollte in der Lage sein, den Code für nicht lokale Vorlagen wiederzuverwenden. – Adrian