size_t sintaxis array c++ templates language-lawyer dependent-type compiler-bug

c++ - array - sizeof en c sintaxis



¿Puede sizeof anidado dos veces alguna vez ser una expresión dependiente? (1)

Noté que gcc 5.0 rechaza el siguiente código, mientras que clang 3.6 lo acepta.

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

Los dos compiladores parecen diferir sobre si sizeof(sizeof(T)) es una expresión dependiente del tipo o dependiente del valor. Si la expresión fuera dependiente, se deduce que I<sizeof(sizeof(T))> es un tipo dependiente, lo que significa que se debe requerir typename .

Esto está cubierto por la siguiente redacción en el estándar C ++ 11:

[temp.dep.type] / 8

Un tipo es dependiente si es

  • un ID de plantilla simple en el que el nombre de la plantilla es un parámetro de plantilla o cualquiera de los argumentos de la plantilla es un tipo dependiente o una expresión que depende del tipo o del valor

[temp.dep.expr] / 4

Las expresiones de los siguientes formularios nunca dependen del tipo de letra (porque el tipo de expresión no puede ser dependiente):

sizeof unary-expression sizeof ( type-id )

[temp.dep.constexpr] / 2

Las expresiones de la siguiente forma son dependientes del valor si la expresión unary o expresión es typedependent o el type-id es dependiente:

sizeof unary-expression sizeof ( type-id )

Mi interpretación es que sizeof(T) nunca puede ser dependiente del tipo, lo que significa que sizeof(sizeof(T)) nunca puede ser dependiente del tipo o dependiente del valor.

¿Es esto un error en gcc?


Estoy usando un borrador posterior a N4296.

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

typename es obligatorio si el anidado-nombre-especificador I<..> depende de un parámetro de plantilla [temp.res] / 5. Entonces, ¿ I<..> dependiente?

[temp.dep.type] / 9 Un tipo es dependiente si es

  • [...]
  • (9.7) un ID de plantilla simple en el que el nombre de la plantilla es un parámetro de plantilla o cualquiera de los argumentos de la plantilla es un tipo dependiente o una expresión que depende del tipo o del valor , o [...]

I<..> es un identificador de plantilla simple , el argumento de plantilla es una expresión. ¿Es esta expresión sizeof(sizeof(T)) dependiente del tipo o dependiente del valor?

La expresión sizeof(sizeof(T)) se puede desglosar en las siguientes expresiones:

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

T no es una expresión, pero lo dejaré en la lista para más adelante. Una nota sobre los paréntesis: Una expresión primaria puede ser una expresión entre paréntesis (general). Una expresión unaria puede ser una expresión de postfijo que puede ser una expresión primaria , por lo tanto, también puede ser entre paréntesis.

Una expresión entre paréntesis (X) depende si X es dependiente:

[temp.dep.expr] / 1 Excepto como se describe a continuación, una expresión depende del tipo si alguna subexpresión depende del tipo.

[temp.dep.constexpr] / 1 Excepto como se describe a continuación, una expresión constante depende del valor si alguna subexpresión depende del valor.

En general, las expresiones sizeof nunca son dependientes del tipo , ya que siempre producen un valor de tipo std::size_t :

[temp.dep.expr] / 4 Las expresiones de los siguientes formularios nunca dependen del tipo de letra (porque el tipo de expresión no puede ser dependiente):

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

Sin embargo, el valor que producen puede depender de un parámetro de plantilla:

[temp.dep.constexpr] / 2 Las expresiones de la siguiente forma dependen del valor si la expresión unary o expresión depende del tipo o el tipo-id es dependiente :

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

Como T depende del tipo de sizeof(T) , sizeof(T) convierte en dependiente del valor . Sin embargo, dado que (sizeof(T)) no depende del tipo , sizeof(sizeof(T)) no depende en absoluto.