2010-11-05 6 views
26

Relacionados con this¿Qué es un especificador de nombre anidado?

Quiero saber exactamente qué es un especificador de nombre anidado? Levanté la vista en el borrador, pero pude entender la gramática, ya que todavía no he tomado ninguna clase de diseño de compilación.

void S(){} 

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

int main(){ 
    struct S *p = new struct ::S; 
    p->::S::f(); 

    S::x; 

    ::S(); // Is ::S a nested name specifier? 
    delete p; 
} 

Respuesta

33

::S es una cualificada Identificación.

En el cualificada Identificación::S::f, S:: es un nombre -anidado-especificador.

En términos informales , un anidada-nombre-especificador es la parte de la Identificación que

  • comienza ya sea en el comienzo de un cualificada Identificación o después de la operador de resolución de alcance inicial (::) si aparece al principio de id y
  • termina con el último operador de resolución de alcance en el id-calificado.

muy informalmente , un Identificación es o bien un cualificada Identificación o un sin reservas-id. Si el id es un id-calificado, en realidad se compone de dos partes: un especificador de nombre anidado seguido de un sin id-.

dado:

struct A { 
    struct B { 
     void F(); 
    }; 
}; 
  • A es un sin reservas-id.
  • ::A es id-calificado pero no tiene nombre-especificador-anotado.
  • A::B es una cualificada Identificación y A:: es un nombre -anidado-especificador.
  • ::A::B es una cualificada Identificación y A:: es un nombre -anidado-especificador.
  • A::B::F es una cualificada Identificación y ambos B:: y A::B:: son -nombre anidado especificadores.
  • ::A::B::F es una cualificada Identificación y ambos B:: y A::B:: son -nombre anidado especificadores.

[1] Esta es una descripción muy inexacta. Es difícil de describir una gramática en la llanura Inglés ...

+0

Cuanto más pienso en ello, cuanto más pienso en este no es una muy buena respuesta. No sé cómo explicarlo en términos simples, pero aún así ser completamente correcto ... –

+1

Poco Q: 'A :: B' -> puedo decir que' A' es ** constructo calificado ** y al mismo tiempo 'A ::' es un especificador de nombre anidado? –

6

Un especificador de espacio de nombres anidada es:

nested-name-specifier : 
    class-or-namespace-name::nested-name-specifier(optional) 

Es decir, una lista no vacía de espacios de nombres y nombres de las clases, cada una seguida por ::, lo que representa una ramificación relativa en el "árbol de espacio de nombres" general del programa. Por ejemplo, my_namespace::, my_namespace::inner_namespace::, my_namespace::my_class:: y my_class::.

Nota específicamente la diferencia a partir de:

qualified-namespace-specifier : 
    ::(optional) nested-name-specifier(optional) class-or-namespace-name 

porque A nested-nombre-especificador no puede ser absoluta (el prefijo :: para referirse al alcance global), mientras que un cualificada espacio de nombres-especificador puede ser , pero no termina con ::.

En su ejemplo, ::S recurra a la función ::S(), y no a la estructura (reglas de precedencia para los que fueron discutidos aquí en Stackoverflow en la pregunta se ha vinculado a al inicio de su pregunta), por lo que no es un nombre anidada especificador.

3

¡Buena pregunta! Aprendí algo nuevo investigando y experimentando en él.

Tiene usted razón en su comentario, ::S(); //Is ::S a nested name specifier <-- Yes, Indeed!

Se podría llegar a apreciar que cuando se inicia la creación de espacios de nombres. Las variables pueden tener los mismos nombres en todos los espacios de nombres y el operador :: es lo que los distingue. Los espacios de nombres son como clases en un sentido, otra capa de abstracción. No quisiera aburrirte con espacios de nombres. El usuario no puede apreciar el nombre especificador anidada en este ejemplo ... considere esto:

#include <iostream> 
using namespace std; 

int count(0);     // Used for iteration 

class outer { 
public: 
    static int count;   // counts the number of outer classes 
    class inner { 
    public: 
     static int count;  // counts the number of inner classes 
    }; 
}; 

int outer::count(42);   // assume there are 42 outer classes 
int outer::inner::count(32768); // assume there are 2^15 inner classes 
           // getting the hang of it? 

int main() { 
    // how do we access these numbers? 
    // 
    // using "count = ?" is quite ambiguous since we don't explicitly know which 
    // count we are referring to. 
    // 
    // Nested name specifiers help us out here 

    cout << ::count << endl;  // The iterator value 
    cout << outer::count << endl;   // the number of outer classes instantiated 
    cout << outer::inner::count << endl; // the number of inner classes instantiated 
    return 0; 
} 

cuenta que he utilizado ::count donde podría haber utilizado simplemente count. ::count se refiere al espacio de nombre global.

Así, en su caso, ya que S() está en el espacio de nombres global (es decir, se ha declarado en el mismo archivo o un archivo incluido o cualquier pieza de código en el que no está envuelto por namespace <name_of_namespace> { }, podría utilizar new struct ::S o new struct S; el que sea así lo prefiere.

acabo de aprender esto como tenía curiosidad de responder a esta pregunta por lo que si usted tiene una respuesta más específica y aprendido, por favor :) Compartir

Cuestiones relacionadas