c++ syntax casting initialization language-lawyer

c++ - Comportamiento estándar para la inicialización directa de cortos sin firmar.



syntax casting (2)

¿Cuál es la razón por la que los tipos calificados unsigned no se pueden inicializar por valor?

Es solo porque solo se puede usar el nombre de tipo de una sola palabra en la expresión de conversión funcional , mientras que el unsigned short no es un nombre de tipo de una sola palabra; short es

La expresión de conversión funcional consiste en un especificador de tipo simple o un especificador de typedef (en otras palabras, un nombre de tipo de una sola palabra: unsigned int(expression) o int*(expression) no son válidos), seguido de una sola expresión entre paréntesis.

Como demostró, puede usar typedef como solución alternativa, o agregar paréntesis para cambiarlo a expresión de estilo C, por ejemplo (unsigned short)(6) o (unsigned short)6 .

De la norma, §7.6.1.3 / 1 Conversión explícita de tipo (notación funcional) [expr.type.conv] :

Un simple-type-specifier o typename-specifier seguido de una lista de expresiones opcionales entre paréntesis o de una lista de iniciados (el inicializador) construye un valor del tipo especificado dado el inicializador.

Y simple-type-specifier :

simple-type-specifier: nested-name-specifier opt type-name nested-name-specifier template simple-template-id nested-name-specifier opt template-name char char16_t char32_t wchar_t bool short int long signed unsigned float double void auto decltype-specifier type-name: class-name enum-name typedef-name simple-template-id decltype-specifier: decltype ( expression ) decltype ( auto )

typename-specifier :

typename-specifier: typename nested-name-specifier identifier typename nested-name-specifier template opt simple-template-id

Noté hoy que en el código de ejemplo:

void print(unsigned short a) { std::cout << a << std::endl; }

Inicialización y uso de trabajos como este:

print(short (5));

Pero no así:

print(unsigned short(6));

main.cpp: 16: 8: error: expresión primaria esperada antes de la impresión "sin firmar" (sin signo corto (6));

Y no tiene que ver con el tipo ya que esto también funciona:

typedef unsigned short ushort; print(ushort (6));

Ejemplo vivo.

Así que fui a buscar lo que dice el estándar sobre la inicialización de valores. Resulta nada:

Los efectos de la inicialización de valores son:

1) Si T es un tipo de clase ...

2) si T es un tipo de clase no sindical ...

2) Si T es un tipo de clase ...

3) si T es un tipo de matriz, ..

4) de lo contrario , el objeto es cero inicializado.

Modificaciones realizadas por legibilidad. Fuente original .

¿Cuáles son las reglas sobre la inicialización de valores de los tipos de POD ? ¿Cuál es la razón por la que los tipos calificados unsigned no se pueden inicializar por valor? ¿Esto tiene más que ver con el hecho de que son rvalues ?


Eso es solo una falla en la gramática: los dos nombres de tipo de palabra no funcionan cuando se crean objetos temporales. Es decir, ninguno de estos trabajos.

template <typename T> void use(T); int main() { use(unsigned int()); use(const int()); use(long long()); }

La solución es utilizar un alias para el tipo respectivo, es decir, todos estos funcionan:

template <typename T> void use(T); int main() { { using type = unsigned int; use(type()); } { using type = const int; use(type()); } { using type = long long; use(type()); } }

Los paréntesis también pueden usarse para la inicialización de valores, aunque requieren el uso de curlies:

template <typename T> void use(T); int main() { use((unsigned int){}); use((const int){}); use((long long){}); }