28 votos

¿Hay construcciones del lenguaje que son válidas para el nombre de tipo pero no para tipos fundamentales?

Me di cuenta de que la pseudo llamada al destructor es válido cuando un tipo de nombre se utiliza, pero no cuando un tipo fundamental se utiliza.

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

Una explicación para lo anterior puede encontrarse en una respuesta a otro post.

Definición de tipo de nombre, desde el C++11 Estándar:

7.1.6.2 especificadores de tipo Simple, p1

tipo de nombre de:
 nombre de clase
 enum nombre
 typedef-nombre
 simple-plantilla-id

Existen otras construcciones de lenguaje que son válidos cuando el especificador de tipo es un tipo de nombre pero no es válido cuando se trata de un tipo fundamental, incluso cuando el tipo de nombre que representa un tipo fundamental, como se muestra arriba?

4voto

Shafik Yaghmour Puntos 42198

No creo que usted encontrará todos los otros casos. Si nos fijamos en el proyecto de C++ estándar Anexo Un resumen de Gramática podemos ver la única otros lugares en la gramática, donde el tipo de nombre de la muestra 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 proporcionan una oportunidad similar que conseguimos 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 es cubierto en la sección 5.2.4 [expr.pseudo] que proporciona para el comportamiento que vemos:

El uso de un pseudo-destructor-nombre después de un punto . o de flecha -> operador representa el destructor para la no-tipo de clase denotada por el tipo de nombre o decltype-especificador. El resultado debe ser utilizado solamente como operando para el operador de llamada de función (), y el resultado de una llamada de tipo void. El único efecto es el de la evaluación de la postfix-expresión antes de que el punto o flecha.

por otro lado, podemos ver las reglas para nested-nombre-especificador en la sección 3.4.3 [basic.de búsqueda.qual] prohibir tal caso:

El nombre de una clase o espacio de estados o enumerador puede ser referido después de la :: operador de resolución de ámbito (5.1) aplicado a una nested-nombre-especificador que denota su clase, espacio de nombres, o la enumeración. Si a :: operador de resolución de ámbito en un nested-nombre-especificador no está precedido por un decltype-especificador de búsqueda el nombre anterior :: considera sólo a los espacios de nombres, tipos, y plantillas de cuyas especialidades son los tipos. Si el nombre que se encuentra no designar un espacio de nombres o de una clase, la enumeración, o de tipo dependiente, el el programa está mal formado

El simple-tipo-especificador caso de no conseguirlo, ya que tipos fundamentales ya están aceptable para este caso.

2voto

bolov Puntos 4005

Hay una diferencia cuando el tipo de valor devuelto 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 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;
}

valores de r para tipos fundamentales no pueden ser modificados. Esto claramente no es el caso de otros tipos, como, por ejemplo, una operación de movimiento debe modificar el temporal desde el que se mueve (por ejemplo, hacer la propietaria puntero nullptr)

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X