Supériorité de l'espace de noms sans nom sur statique?

130

En quoi les espaces de noms sans nom sont-ils supérieurs au staticmot-clé?

Nawaz
la source
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 code
   static int sample_function() { /* function body */ }
   static int sample_variable;

Mais ce code n'est PAS valide:

   //illegal code
   static class sample_class { /* class body */ };
   static struct sample_struct { /* struct body */ };

Donc, la solution est, un espace de noms sans nom, qui est ceci,

   //legal code
   namespace 
   {  
        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).

Nawaz
la source
11
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.

SasQ
la source
3
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.

Salgar
la source
5
Non, ce n'est pas le cas. Un brouillon l'a fait. Et un autre projet très peu de temps après a annulé ce changement stupide.
underscore_d