2014-12-30 6 views
16

Ich bemerkte, dass gcc 5.0 den folgenden Code ablehnt, während clang 3.6 es akzeptiert.Kann sizeofverted zweimal je ein abhängiger Ausdruck sein?

template<int n> 
struct I 
{ 
    typedef int Type; 
}; 

template<typename T> 
struct A 
{ 
    typedef I<sizeof(sizeof(T))>::Type Type; 
}; 

Die beiden Compilern scheinen zu unterscheiden, ob ein Ausdruck sizeof(sizeof(T)) typabhängig oder Wert-abhängig ist. Wenn der Ausdruck abhängig ist, dann folgt, dass I<sizeof(sizeof(T))> ein abhängiger Typ ist, was bedeutet, dass typename erforderlich sein sollte.

Dies wird durch die folgende Formulierung in der C++ 11-Standard behandelt:

[temp.dep.type]/8

A-Typ abhängig ist, ob es

    ist
  • Eine Simple-Template-ID, bei der entweder der Vorlagenname ein Vorlagenparameter oder ist. Alle Argumente der Vorlage sind ein abhängiger Typ oder ein Ausdruck, der typabhängig oder wertabhängig ist

[temp.dep.expr]/4

Ausdrücke der folgenden Formen sind nie typabhängig (weil die Art des Ausdrucks kann nicht abhängig sein):

sizeof unary-expression 
sizeof (type-id) 

[temp.dep.constexpr]/2

Ausdrücke des folgenden Formulars sind wertabhängig, wenn der unäre Ausdruck oder Ausdruck typenabhängig ist oder die Typ-ID ist abhängig:

sizeof unary-expression 
sizeof (type-id) 

Meine Interpretation ist, dass sizeof(T) nie typabhängig sein kann, sizeof(sizeof(T)) Sinn kann nie typabhängig oder wertabhängig sein.

Ist das ein Fehler in gcc?

+1

Oh. GCC denkt auch, dass "sizeof n" abhängig ist. http: // melon.org/wandbox/permlink/BLobLBzkQXNRfDuq – willj

+0

Nun, 'sizeof n' ist nicht typabhängig, sondern wertabhängig. 'sizeof X', wobei' X' nicht * typabhängig ist, ist überhaupt nicht abhängig. Daher muss "sizeof sizeof n" nicht abhängig sein, nein? – dyp

+0

Interessant kompiliert auf gcc 4.7.2, schlägt aber auf 4.9.0 fehl. – Barry

Antwort

7

Ich benutze einen post-N4296 Entwurf.

typedef I<sizeof(sizeof(T))>::Type Type; 

typename erforderlich, wenn der verschachtelten-name-specifierI<..> auf einem Template-Parametern abhängig [temp.res]/5. Also, ist I<..> abhängig?

[temp.dep.type]/9 A-Typ abhängig ist, ob es

ist
  • [...]
  • (9,7) ein einfache -template-ID in denen entweder der Vorlagenname ist ein Vorlagenparameter oder eines der Vorlagenargumente ist ein abhängiger Typ oder ein Ausdruck, der typabhängig oder wertabhängig ist oder [...]

I<..> asimple-Template-ID ist, ist das Template-Argument ein Ausdruck. Ist dieser Ausdruck sizeof(sizeof(T)) typabhängig oder wertabhängig?

Der Ausdruck sizeof(sizeof(T)) lässt sich in die folgenden Ausdrücke unterteilt werden:

 
expression   form 
=============================================== 
       T  type-id 
     sizeof(T)  sizeof (type-id) 
     (sizeof(T)) (expression) 
sizeof(sizeof(T)) sizeof unary-expression 

T kein Ausdruck ist, aber ich werde es für später in der Liste verlassen. Eine Anmerkung zu den Klammern: A primärer Ausdruck kann ein geklammerter (allgemein) Ausdruck sein. A unary-Ausdruck kann ein Postfix-Ausdruck sein, die eine Primärexpression sein kann, daher kann es auch in Klammern gesetzt werden.

A klammerte Ausdruck (X) abhängig ist, wenn X abhängt:

[temp.dep.expr]/1 Mit der Ausnahme, wie unten beschrieben, ein Ausdruck typabhängig ist, wenn ein subexpression typabhängig ist.

[temp.de.contexpr]/1 Außer wie unten beschrieben, ist ein konstanter Ausdruck wertabhängig, wenn ein Unterausdruck wertabhängig ist.

Im Allgemeinen sizeof Ausdrücke sind nie Typ -abhängigen, weil sie immer einen Wert vom Typ produzieren std::size_t:

[temp.dep.expr]/4 Ausdrücke der folgenden Formen nie typabhängig (weil die Art des Ausdrucks kann nicht abhängig sein):

[...] 
sizeof unary-expression 
sizeof (type-id) 

Jedoch kann der Wert, den sie liefern auf einem Template-Parameter abhängig sein:

[temp.dep.constexpr]/2 Ausdruck der folgenden Form ist wertabhängige, wenn die unären-expression oder Ausdruck ist typabhängig oder der Typ-ID hängt:

sizeof unary-expression 
sizeof (type-id) 
 
expression   form      value-dep? type-dep? 
======================================================================= 
       T  type-id     no   yes 
     sizeof(T)  sizeof (type-id)   yes   no 
     (sizeof(T)) (expression)    yes   no 
sizeof(sizeof(T)) sizeof unary-expression no   no 

Seit T ist Typ-abhängig, sizeof(T) wird Wert-abhängig. Da jedoch (sizeof(T))nicht Typ-abhängig ist, ist sizeof(sizeof(T)) überhaupt nicht abhängig.

+0

Guter Punkt auf der äußeren Klammer. Aus irgendeinem Grund bin ich fest verdrahtet, um 'sizeof (Ausdruck)' zu schreiben – willj