2017-11-15 16 views
1

nach ISO 14882: 2011 § 14.6.2.1:Einfacher Typspezifizierer ist Template-Parameter

A-Typ abhängig ist, wenn es ist - ein Template-Parameter,

Und nach ISO § 14882 : 2011 14.6:

ein Name in einer Template-Deklaration oder Definition verwendet und das ist abhängig von einem Template-Parameter wird angenommen, dass kein Typ, es sei dennzu nennen 210 Die zutreffende Namenssuche findet einen Typnamen, oder der Name ist mit dem Schlüsselwort typename.

Aber

template <typename T> class U 
{ 
    typename T t; // ill-formed, i have an compilier error 
}; 

sind "abhängige Name" und "Name in einer Template-Deklaration oder Definition verwendet und das ist abhängig von einem Template-Parameter" das gleiche Konzept? Ich versuche, mein Missverständnis zu lösen, da es als Kollision zwischen Behauptungen in Standard (ISO 14882: 2011 § 14.6.2.1) und Beispiel aus Standard T t aussieht.

+1

Was ist die eigentliche Frage? – Barry

+0

'typename T t;' ist schlecht gebildet, weil [die Grammatik einen geschachtelten Namen erfordert] (http://eel.is/c++draft/temp.res#3). – cpplearner

+0

Grammatik erfordert nicht verschachtelten Namen Specifier überall für Typname, seinen einzigen besonderen Fall für obligate Verwendung von Typname. Es gibt viele Fälle, in denen Typname erforderlich ist, aber der Spezifizierer für verschachtelte Namen wird nicht angewendet. Zum Beispiel p .x – Pupkin

Antwort

1

Ihr Beispielcode ist schlecht formatiert, da der ISO-Abschnitt 17.7.3 (http://eel.is/c++draft/temp.res#3) nicht nested name-specifier ist.

Daher gibt es keine Möglichkeit T kann etwas anderes als die typename T als Vorlage Parameter verwendet werden. I.e. Der Compiler kann nicht falsch sein, Sie müssen ihn also nicht mit der typename-specifier qualifizieren.

Ein Beispiel für einen abhängigen Typ, bei dem die typename-specifier erforderlich ist T::value_type wäre, weil der tatsächliche Typ/Wert von value_type hängt davon ab, was T ist. In diesem Fall müssen Sie den Compiler helfen:

template <typename T> class U { 
    using t = T;      // OK 
    using u = T::value_type;   // ill-formed: needs typename-specifier 
    using v = typename t::value_type; // OK: qualified with typename keyword 
}; 

Angenommen, Sie haben die folgende:

class foo { 
    constexpr static int value_type = 7; 
} 

class bar { 
    using value_type = int; 
} 

Dies ist der Grund, die zweite über typedef Linie ist schlecht gebildet: wenn T ist foo dann ist value_type eigentlich kein Typ, sondern eine Konstante mit einem sehr verwirrenden Namen. Wenn T ist bar dann ist alles in Ordnung. Aber der Compiler kann das nicht wissen, also musst du ihm helfen und ihm versichern, dass value_type tatsächlich ein Typ ist. Das bedeutet auch, dass Sie mit einem Kompilierungsfehler begrüßt werden, wenn Sie versuchen, U<foo> zu kompilieren.

Hinweis: Ich habe C++ 11 Syntax für die Typedefs verwendet, weil ich es viel lesbarer finde. Die obige Erklärung gilt immer noch, wenn Sie typedef anstelle von using verwenden.

+0

> "' T' ist kein abhängiger Name in Ihrem Beispiel. " Warum? Gemäß ISO 14882: 2011 § 14.6.2.1: Ein Typ ist abhängig, wenn es - ein Vorlagenparameter ist, Und abhängiger Typ ist eine Art abhängiger Name gemäß Standard. – Pupkin

+0

Bitte begründen Sie Ihre Antwort nach ISO 14882 – Pupkin

+0

Ich habe einen Fehler erhalten. siehe http://www.wandbox.org/permlink/FIMBqI579385nbhy Wie erklären Sie, dass der Standard besagt: 14882: 2011 § 14.6.2.1: Ein Typ ist abhängig, wenn es - ein Template-Parameter ist, ??? – Pupkin

Verwandte Themen