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.