7
votes

Espaces de noms ayant un espace de noms sans nom avec la même variable déclarée

J'ai essayé ce code factice ci-dessous pour tester l'espace de noms sans nom.

J'ai la sortie suivante p> xxx pré>

Je suis un peu confus à ce sujet. P>

  • Je m'attendais à une erreur du compilateur disant qu'il ne peut pas résoudre une ambiguïté concernant A :: m_a code>. Au lieu de cela, il fait toujours référence à la moins imbriqué. Est-ce toujours le cas? Quelles règles C ++ suit? LI>
  • Il semble que le compilateur crée une variable CMYOBJ à la suite de la commande écrit sur le fichier. Est-ce toujours le cas? LI>
  • Y a-t-il un moyen d'accéder à la variable code> m_a code> la plus imbriquée de principal () code>?. li> OL>
    class CMyObj{     
        public:
        CMyObj(int a){std::cout  << "ctor " << a << std::endl; }
     };
     namespace a{ 
          namespace{
               int m_a=4;
               int m_b=5;
               CMyObj m_obj(1);
          }  
     }
     namespace a{
          int m_a=3;
          CMyObj m_obj(0);
     }
     int main(){
          std::cout << a::m_a << std::endl; // which one?
          std::cout << a::m_b << std::endl; // how this is possible?
          return 0;
     }
    

  • 0 commentaires

    4 Réponses :


    1
    votes

    Je dois prendre le temps de trouver les définitions exactes dans la spécification, mais lorsque vous avez un espace de noms anonyme (Sans nom), le compilateur génère en fait un nom mangelé. Lorsque vous écrivez

    a::m_b 
    


    1 commentaires

    "Je ne pense pas qu'il y ait un moyen d'accéder à la copie de l'espace de noms non nomé de M_A à ce stade." - Il semble que vous puissiez ouvrir à nouveau l'espace de noms sans nom pour ajouter une fonction / alias d'accesseur.



    3
    votes

    Je n'ai pas de standard C ++ 03 avec moi pour vérifier le libellé là-bas, alors je citerai de FDIS N3290. Je pense que la réponse à cette question se trouve dans les règles de recherche de nom qualifiées dans 3.4.3.2/2:

    Pour un espace de noms X et Nom M, l'ensemble de recherche qualifié de noms S (x, m) est défini comme suit: Soit S0 (x, m) être l'ensemble de toutes les déclarations de M in x et le jeu d'espace de noms en ligne de x (7.3.1). Si S0 (x, M) n'est pas vide, S (x, m) est S0 (x, m); Sinon, s (x, m) est l'union de S (NI, M) pour tous les espaces de noms Ni désignés par l'utilisation de directives dans X et son jeu d'espace de noms en ligne.

    Maintenant, rappelez-vous que l'espace de noms sans nom est un espace de noms nommé unique avec une directive à l'aide de la directive.


    2 commentaires

    Cette dernière phrase est la clé. Merci.


    Salut Gene! Merci beaucoup pour votre réponse (venir avec un délai)!



    1
    votes

    Premier consulter ce code simplifié (et mon explication simplifiée, vous pouvez lire §3.4.3.2 pour les détails): XXX

    Considérez ce qui se passe lorsque nous disons A: : x . Premièrement, le compilateur énumère toutes les déclarations de x dans a . S'il trouve un x sans ambiguïté, il se termine avec succès. Sinon, il cherche récursivement les espaces de noms déclarés par une directive à l'aide de la directive. S'il ne trouve jamais de résultat, le programme est mal formé. xxx

    ici, il ne trouve pas x dans b < / Code>, il recherche donc l'espace de noms A (en raison de l'utilisation de la directive) et le trouve. Il devrait maintenant avoir du sens pourquoi ce n'est pas ambigu: xxx

    ici il trouve le x dans b et jamais considère a . Maintenant, considérons simplement qu'un espace de noms non nomé est en réalité un espace de noms avec un nom inconnu unique: xxx

    comme avant, le x dans b se trouve sans envisager l'espace de noms non nommé. Votre code est similaire.


    1 commentaires

    J'aime votre explication détaillée.



    0
    votes

    Il n'y a pas d'ambiguïté car la portée de Espace de noms :: :: m_a code> est l'espace de noms externe ( Espace de noms :: A code>). Il n'y a aucun moyen d'accéder à Espace de noms :: :: m_a code> dans la fonction principale et c'est pourquoi il n'y a pas d'ambiguïté. Essayez de compiler pour compiler le code suivant et vous obtiendrez l'erreur suivante:

    namespace ns{
      namespace {
        int a = 2;
      }
      int a = 3;
      int c = a;
    }
    


    0 commentaires