Cependant, les espaces de noms sans nom ne sont pas un remplacement suffisant pour les espaces de noms statiques , selon le comité des normes. Il existe encore quelques cas où les espaces de noms sans nom échouent et ne staticfonctionnent que.
legends2k
Réponses:
134
Vous faites essentiellement référence à la section §7.3.1.1 / 2 du Standard C ++ 03,
L'utilisation du mot clé static est déconseillée lors de la déclaration d'objets dans une étendue d'espace de noms; l'espace de noms sans nom fournit une alternative supérieure.
Notez que ce paragraphe a déjà été supprimé dans C ++ 11. staticles fonctions standard ne sont plus obsolètes!
Néanmoins, les espaces de noms sans nom sont supérieurs au mot-clé static, principalement parce que le mot-clé statics'applique uniquement aux déclarations et fonctions de variables , et non aux types définis par l'utilisateur .
Le code suivant est valide en C ++
//legal codestaticint sample_function(){/* function body */}staticint sample_variable;
Mais ce code n'est PAS valide:
//illegal codestaticclass sample_class {/* class body */};staticstruct sample_struct {/* struct body */};
Donc, la solution est, un espace de noms sans nom, qui est ceci,
//legal codenamespace{class sample_class {/* class body */};struct sample_struct {/* struct body */};}
J'espère qu'il explique que pourquoi unnamed-namespaceest supérieur à static.
Notez également que l'utilisation du mot-clé static est déconseillée lors de la déclaration d'objets dans une étendue d'espace de noms (selon la norme).
Plus généralement, un espace de noms sans nom permet une liaison externe. C'est ce qui active la déclaration de classe local-to-translation-unit. Il permet également, par exemple, la constante de chaîne de liaison externe, à utiliser comme argument de modèle.
Bravo et hth. - Alf
10
Comme l'a noté Fred Nurk sur une autre de vos réponses, il semble que cette deprecatedremarque ait été supprimée du dernier C ++ 0x FCD (n3225).
Matthieu M.
36
Vous répondez à votre propre question et dites merci à vous-même: -o
manpreet singh
12
Quelle serait la différence de simplement définir la classe dans le cpp (pas d'espace de noms anonyme, pas de statique)?
Luchian Grigore
6
@LuchianGrigore Les problèmes de liaison dans le cas 2 .cppdéfinissent une classe avec le même nom.
Xaqq
8
Il y a un problème intéressant lié à ceci:
Supposons que vous utilisiez des staticmots clés ou sans nom namespacepour rendre une fonction interne au module (unité de traduction), puisque cette fonction est destinée à être utilisée en interne par le module et non accessible en dehors de celui-ci. (Les namespaces sans nom ont l'avantage de rendre les définitions de données et de types internes, en plus des fonctions).
Avec le temps, le fichier source de l'implémentation de votre module devient volumineux et vous souhaitez le diviser en plusieurs fichiers source séparés, ce qui permettrait de mieux organiser le code, de trouver les définitions plus rapidement et d'être compilé indépendamment.
Mais maintenant vous êtes confronté à un problème: ces fonctions ne peuvent plus appartenir staticau module, car elles staticne font pas réellement référence au module , mais au fichier source (unité de traduction). Vous êtes obligé de les rendre non - staticpour leur permettre d'accéder à partir d'autres parties (fichiers objets) de ce module. Mais cela signifie aussi qu'ils ne sont plus cachés / privés du module: ayant un lien externe, ils sont accessibles depuis d'autres modules, ce qui n'était pas votre intention initiale.
Unnamed namespacene résoudrait pas non plus ce problème, car il est également défini pour un fichier source particulier (unité de traduction) et n'est pas accessible de l'extérieur.
Ce serait formidable si l'on pouvait spécifier que certains namespacesont private, c'est-à-dire que tout ce qui y est défini, est destiné à être utilisé en interne par le module auquel il appartient. Mais bien sûr, C ++ n'a pas de concept de "modules", seulement des "unités de traduction", qui sont étroitement liées aux fichiers source.
Ce serait de toute façon un hack et une solution limitée, mais vous pouvez inclure le (s) fichier (s) cpp avec les fonctions internes statiques ou d'espacement de noms dans vos fichiers cpp «principaux». Ensuite, excluez ces fichiers cpp «satellites» de la construction et vous avez terminé. Le seul problème si vous avez deux fichiers cpp `` principaux '' ou plus et qu'ils veulent tous les deux utiliser cette fonction géniale à partir de l'un des fichiers cpp `` satellite '' ...
Sergey
L'utilisation de l'héritage avec private / protected / public avec des fonctions statiques n'est-elle pas la solution?
Ali
C ++ 20 introduit des modules, qui résout votre problème.
LF
4
Le standard C ++ lit dans la section 7.3.1.1 Espaces de noms sans nom, paragraphe 2:
L'utilisation du mot-clé static est déconseillée lors de la déclaration d'objets dans une étendue d'espace de noms, l'espace de noms sans nom fournit une alternative supérieure.
La statique s'applique uniquement aux noms d'objets, de fonctions et d'unions anonymes, pas aux déclarations de type.
static
fonctionnent que.Réponses:
Vous faites essentiellement référence à la section §7.3.1.1 / 2 du Standard C ++ 03,
Notez que ce paragraphe a déjà été supprimé dans C ++ 11.
static
les fonctions standard ne sont plus obsolètes!Néanmoins, les espaces de noms sans nom sont supérieurs au mot-clé static, principalement parce que le mot-clé
static
s'applique uniquement aux déclarations et fonctions de variables , et non aux types définis par l'utilisateur .Le code suivant est valide en C ++
Mais ce code n'est PAS valide:
Donc, la solution est, un espace de noms sans nom, qui est ceci,
J'espère qu'il explique que pourquoi
unnamed-namespace
est supérieur àstatic
.Notez également que l'utilisation du mot-clé static est déconseillée lors de la déclaration d'objets dans une étendue d'espace de noms (selon la norme).la source
deprecated
remarque ait été supprimée du dernier C ++ 0x FCD (n3225)..cpp
définissent une classe avec le même nom.Il y a un problème intéressant lié à ceci:
Supposons que vous utilisiez des
static
mots clés ou sans nomnamespace
pour rendre une fonction interne au module (unité de traduction), puisque cette fonction est destinée à être utilisée en interne par le module et non accessible en dehors de celui-ci. (Lesnamespace
s sans nom ont l'avantage de rendre les définitions de données et de types internes, en plus des fonctions).Avec le temps, le fichier source de l'implémentation de votre module devient volumineux et vous souhaitez le diviser en plusieurs fichiers source séparés, ce qui permettrait de mieux organiser le code, de trouver les définitions plus rapidement et d'être compilé indépendamment.
Mais maintenant vous êtes confronté à un problème: ces fonctions ne peuvent plus appartenir
static
au module, car ellesstatic
ne font pas réellement référence au module , mais au fichier source (unité de traduction). Vous êtes obligé de les rendre non -static
pour leur permettre d'accéder à partir d'autres parties (fichiers objets) de ce module. Mais cela signifie aussi qu'ils ne sont plus cachés / privés du module: ayant un lien externe, ils sont accessibles depuis d'autres modules, ce qui n'était pas votre intention initiale.Unnamed
namespace
ne résoudrait pas non plus ce problème, car il est également défini pour un fichier source particulier (unité de traduction) et n'est pas accessible de l'extérieur.Ce serait formidable si l'on pouvait spécifier que certains
namespace
sontprivate
, c'est-à-dire que tout ce qui y est défini, est destiné à être utilisé en interne par le module auquel il appartient. Mais bien sûr, C ++ n'a pas de concept de "modules", seulement des "unités de traduction", qui sont étroitement liées aux fichiers source.la source
Le standard C ++ lit dans la section 7.3.1.1 Espaces de noms sans nom, paragraphe 2:
La statique s'applique uniquement aux noms d'objets, de fonctions et d'unions anonymes, pas aux déclarations de type.
la source