una todas que página programar pasos paso para pagina las etiquetas estructura cuál crear como básica aprender c++

c++ - todas - ¿Existen construcciones de lenguaje que sean válidas para el nombre de tipo pero no para los tipos fundamentales?



que es title en html (2)

Noté que la llamada de pseudo destructor es válida cuando se usa un nombre de tipo pero no cuando se usa un tipo fundamental.

typedef int BType; int b; b.~BType(); // Legal b.~int(); // Not legal

Se puede encontrar una explicación de lo anterior en una respuesta a otra publicación de SO .

Definición de nombre-tipo , del estándar C ++ 11:

7.1.6.2 Especificadores de tipo simple, p1

type-name: class-name enum-name typedef-name simple-template-id

¿Hay otras construcciones de lenguaje que sean válidas cuando el especificador de tipo es un nombre de tipo pero no es válido cuando es un tipo fundamental incluso cuando el nombre de tipo representa un tipo fundamental, como se muestra arriba?


Hay una diferencia cuando el tipo de retorno de una función es un tipo fundamental o no:

struct X{}; template <class T> auto foo() { // one liner []() -> T { return T{}; }() = T{}; // invalid for T fundamental type // or more clear: auto get_t = []() -> T { return T{}; }; get_t() = T{}; // invalid for T fundamental type } auto main() -> int { foo<X>(); // valid foo<int>(); // invalid return 0; }

Sin plantillas, para ser aún más claro:

struct X{}; auto ret_x() -> X { return X{}; } auto ret_int() -> int { return int{}; } auto main() -> int { ret_x() = X{}; // valid ret_int() = int{}; // invalid return 0; }

Los valores para los tipos fundamentales no pueden ser modificados. Claramente, este no es el caso para otros tipos, ya que, por ejemplo, una operación de movimiento debe modificar el temporal desde el que se mueve (por ejemplo, hacer que el puntero propietario nullptr)


No creo que encuentre otros casos. Si observamos el borrador de la norma C ++, anexo A, resumen de gramática , podemos ver que las otras ubicaciones en la gramática donde se muestra el nombre de tipo son:

nested-name-specifier: :: type-name :: namespace-name :: decltype-specifier :: nested-name-specifier identifier :: nested-name-specifier templateopt simple-template-id ::

y:

simple-type-specifier: nested-name-specifieropt type-name [...]

Ninguno de los cuales brinda una oportunidad similar a la que tenemos con el pseduo-destructor, que tiene la siguiente gramática:

pseudo-destructor-name: nested-name-specifieropt type-name :: ~ type-name nested-name-specifier template simple-template-id :: ~ type-name nested-name-specifieropt~ type-name ~ decltype-specifier

y está cubierto en la sección 5.2.4 [expr.pseudo] que proporciona el comportamiento que vemos:

El uso de un nombre de pseudo-destructor después de un punto. o flecha -> operador representa el destructor para el tipo que no es de clase indicado por type-name o decltype-specifier. El resultado solo se utilizará como el operando del operador de llamada de función (), y el resultado de dicha llamada tiene el tipo void. El único efecto es la evaluación de la expresión postfix antes del punto o flecha.

por otro lado, podemos ver las reglas para el especificador de nombre anidado en la sección 3.4.3 [basic.lookup.qual] prohibir tal caso:

Se puede hacer referencia al nombre de un miembro de una clase o espacio de nombres o un enumerador después de que el operador de resolución de alcance (5.1) se aplique a un especificador de nombre anidado que denota su clase, espacio de nombres o enumeración. Si un operador de :: resolución de alcance en un especificador de nombre anidado no está precedido por un especificador de tipo decl, la búsqueda del nombre que precede a eso :: considera solo espacios de nombres, tipos y plantillas cuyas especializaciones son tipos. Si el nombre encontrado no designa un espacio de nombres o una clase, enumeración o tipo dependiente, el programa está mal formado

El caso del especificador de tipo simple tampoco nos lleva allí, ya que los tipos fundamentales ya son aceptables para este caso.