Pregunta

  

$ 10.2 / 4 "[Nota: Mirando hacia arriba en un nombre   un elaborado de tipo-especificador (3.4.4)   o base-especificador (Cláusula 10), para   ejemplo, ignora todo tipológicas   declaraciones, mientras mira hacia arriba un nombre   en un nombre-especificador anidado (3.4.3)   hace caso omiso de la función, variable y   declaraciones empadronador ".

He encontrado que esta afirmación es muy confuso en esta sección mientras que describe sobre la búsqueda de nombres.

void S(){}

struct S{
   S(){cout << 1;}
   void f(){}
   static const int x = 0;
}; 

int main(){ 
   struct S *p = new struct ::S;  // here ::S refers to type
   p->::S::f();

   S::x;  // base specifier, ignores the function declaration 'S'

   ::S(); // nested name specifier, ignores the struct declaration 'S'.
   delete p;
} 

Mis preguntas:

  1. Es mi comprensión de las reglas correcta?

  2. ¿Por qué ::S en la línea de hacer nuevos tratados de forma automática a S media estructura, mientras que en los medios ::S última línea de las funciones S en el espacio de nombres global.

  3. ¿este punto a una ambigüedad en la documentación, o se trata de otro día más para que me quede lejos de C ++ estándar?

¿Fue útil?

Solución

Q1: Creo que sí

.

P2: Compatibilidad con C. Cuando se declara una struct en C, el nombre de la etiqueta es sólo eso, un nombre de etiqueta. Para poder utilizarlo de manera independiente, se necesita un typedef. En C ++ que no es necesario el typedef, que hace vivir más fácil. Pero las reglas de C ++ se han complicado por la necesidad de ser capaz de importar cabeceras ya existentes de C, que "sobrecarga", el nombre de la etiqueta con un nombre de función. El ejemplo canónico de que es la función stat() Unix que utiliza un struct stat* como argumento.

P3: lectura estándar suele ser bastante difícil ... lo que necesita saber ya que no hay lugar en otro lugar la modificación de lo que está leyendo. No es extraño que la gente saber cómo hacer que sean abogado idioma ...

Otros consejos

Estás equivocado con respecto a la segunda observación. En S::x, la S es un nombre en un nombre especificador anidada. Lo que el estándar se refiere a la "base-especificador" es la siguiente

namespace B { struct X { }; void X() }
struct A : B::X { }; // B::X is a base-specifier

También es no es correcto en esto:

  

::S(); // nombre anidado especificador, hace caso omiso de la declaración struct 'S'.`

Este código llama a la función no porque ::S sería un especificador de nombre anidado (que no es un nombre anidado-especificador!), Sino porque los nombres de función ocultan los nombres de clase o de enumeración si tanto la función como la clase / enumeración se declaran en el mismo ámbito.

Fwiw, el siguiente código sería igualmente válido para la línea 2 de su principal

p->S::f();

Lo que es importante es que los preceedes S un ::, lo que hace que las operaciones de búsqueda ignorar la función. Que se pone :: antes S no tiene ningún efecto en su caso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top