J'ai essayé ce code factice ci-dessous pour tester l'espace de noms sans nom.
J'ai la sortie suivante p> Je suis un peu confus à ce sujet. P>
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>
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;
}
4 Réponses :
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
"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.
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: P>
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. P> blockQuote>
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. P>
Cette dernière phrase est la clé. Merci.
Salut Gene! Merci beaucoup pour votre réponse (venir avec un délai)!
Premier consulter ce code simplifié (et mon explication simplifiée, vous pouvez lire §3.4.3.2 pour les détails): Considérez ce qui se passe lorsque nous disons ici, il ne trouve pas ici il trouve le comme avant, le A: : x code>. Premièrement, le compilateur énumère toutes les déclarations de
x code> dans
a code>. S'il trouve un
x code> 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é. P>
x code> dans
b < / Code>, il recherche donc l'espace de noms
A code> (en raison de l'utilisation de la directive) et le trouve. Il devrait maintenant avoir du sens pourquoi ce n'est pas ambigu: p>
x code> dans
b code> et jamais considère
a code>. Maintenant, considérons simplement qu'un espace de noms non nomé est en réalité un espace de noms avec un nom inconnu unique: p>
x code> dans
b code> se trouve sans envisager l'espace de noms non nommé. Votre code est similaire. P> p>
J'aime votre explication détaillée.
Il n'y a pas d'ambiguïté car la portée de Espace de noms ::
Espace de noms :: A code>). Il n'y a aucun moyen d'accéder à
Espace de noms ::
namespace ns{
namespace {
int a = 2;
}
int a = 3;
int c = a;
}