Qu'est-ce qu'un spécificateur de nom imbriqué?

liée à cette

je veux savoir ce qu'est exactement un spécificateur de nom imbriqué? J'ai cherché dans le projet mais je pouvais comprendre la grammaire car je n'ai pas encore pris de cours de conception de compilateur.

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;
} 
26
demandé sur Community 2010-11-05 08:19:30

3 réponses

::S est un qualifié " id .

dans le qualifié-id ::S::f , S:: est un emboîté-spécificateur de nom .

En termes informels 1 , un nested-nom-spécificateur est la partie de la id que

  • commence soit au très début d'un qualifié-id ou après l'opérateur de résolution de portée initiale ( :: ) si on apparaît au tout début du id et
  • se termine avec le dernier opérateur de résolution de portée dans la qualifié " id .

de façon très informelle 1 , un id est un qualifié-id ou an unqualified-id . Si le id est un qualified-id , il est en fait composé de deux parties: un spécificateur de nom imbriqué suivi d'un unqualified-id .

:

struct  A {
    struct B {
        void F();
    };
};
  • A est un non qualifié-id .
  • ::A est un qualifiée de l'id mais n'a pas imbriqué-spécificateur de nom .
  • A::B est un qualifié " id et A:: est un nested-nom-spécificateur .
  • ::A::B est un qualifié " id et A:: est un nested-nom-spécificateur .
  • A::B::F est un qualifié-id et les deux B:: et A::B:: sont imbriqués-spécificateurs de nom .
  • ::A::B::F est un qualifié " id et les deux B:: et A::B:: sont nested-nom-prescripteurs .

[1] c'est une description inexacte. C'est difficile de décrire une grammaire en anglais...

33
répondu James McNellis 2010-11-05 05:44:32

un spécificateur d'espace de noms imbriqué est:

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

C'est-à-dire une liste non vide d'espaces de noms et de noms de classe, chacun suivi de::, représentant une ramification relative dans l'ensemble de l '"arbre des espaces de noms" du programme. Par exemple, my_namespace:: , my_namespace::inner_namespace:: , my_namespace::my_class:: , et my_class:: .

noter spécifiquement la différence entre:

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

en ce qu'un spécificateur de nom imbriqué ne peut pas être absolu (préfixé avec :: pour se référer à la portée globale), alors qu'un spécificateur d'espace de noms qualifié peut l'être, mais ne se termine pas avec :: .

dans votre exemple, ::S se résout à la fonction ::S() , et non à la structure (règles de précendance pour qui ont été discutées ici sur Stackoverflow dans la question que vous avez liée au début de votre question), de sorte qu'il n'est pas un spécificateur de nom imbriqué.

6
répondu Tony Delroy 2013-03-26 13:22:12

bonne question! J'ai appris quelque chose de nouveau en faisant des recherches et des expériences.

vous avez raison dans votre commentaire, ::S(); //Is ::S a nested name specifier <-- Yes, Indeed!

vous l'apprécierez quand vous commencerez à créer des namespaces. Les Variables peuvent avoir les mêmes noms à travers les espaces de noms et l'opérateur :: est ce qui les distingue. Les Namespaces sont comme des classes dans un sens, une autre couche d'abstraction. Je ne voudrais pas vous ennuyer avec des noms d'espaces. Vous ne pouvez pas appréciez le spécificateur de nom imbriqué dans cet exemple...considérez celui-ci:

#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;
}

notez que j'ai utilisé ::count où j'aurais pu simplement utiliser count . ::count se réfère à l'espace de noms global.

donc dans votre cas, puisque S () est dans l'espace Nam global (i.e. il est déclaré dans le même fichier ou un fichier inclus ou n'importe quel morceau de code où il n'est pas Enveloppé par namespace <name_of_namespace> { } , vous pouvez utiliser new struct ::S ou new struct S ; selon ce que vous préférez.

je viens d'apprendre cela car j'étais curieux de répondre à cette question donc si vous avez une réponse plus spécifique et appris, s'il vous plaît partager:)

3
répondu iGbanam 2010-11-05 06:46:18