145 votes

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

En quoi les espaces de noms non nommés sont-ils supérieurs à l'espace de noms static mot-clé ?

0 votes

Toutefois, les espaces de noms non nommés ne remplacent pas suffisamment les espaces de noms espace nominatif statique selon le comité de normalisation. Il existe encore quelques cas où les espaces de noms non nommés échouent et où seuls les espaces de noms non nommés peuvent être utilisés. static œuvre.

148voto

Nawaz Points 148870

Vous êtes essentiellement en se référant à la section $7.3.1.1/2 de la Norme C++,

L'utilisation du mot-clé static est obsolète lors de la déclaration d'objets dans un espace de noms de la portée; le sans nom d'espace de noms fournit un supérieur alternative.

Sans nom d'espace de noms est supérieure à mot-clé static, principalement parce que le mot-clé static ne s'applique qu'aux variables déclarations et les fonctions, de ne pas définis par l'utilisateur types.

Le code suivant est valide en C++

   //legal code
   static int sample_function() { /* function body */ }
   static int sample_variale;

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, sans nom d'espace de noms, qui est-ce,

   //legal code
   namespace 
   {  
        class sample_class { /* class body */ };
        struct sample_struct { /* struct body */ };
   }

Espérons qu'il explique pourquoi unnamed-namespace est supérieure à static.

Aussi, notez que l'utilisation du mot-clé static est déconseillé lors de la déclaration d'objets dans un espace de noms portée (selon la Norme).

12 votes

Plus généralement, un espace de noms sans nom permet d'établir des liens externes. C'est ce qui permet la déclaration de classe de l'unité locale à l'unité de traduction. Il permet également, par exemple, d'utiliser une constante de chaîne de caractères à lien externe comme argument de modèle.

0 votes

@Alf : C'est vrai. Merci pour l'ajout :-)

10 votes

Comme l'a fait remarquer Fred Nurk dans une autre de vos réponses, il semble que cette deprecated a été supprimée de la dernière version du FCD C++0x (n3225).

10voto

SasQ Points 2332

Un problème intéressant se pose à cet égard :

Supposons que vous utilisiez static mot-clé ou sans nom namespace 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 n'est pas accessible en dehors de celui-ci. (Sans nom namespace 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 souhaiteriez le diviser en plusieurs fichiers sources distincts, ce qui permettrait de mieux organiser le code, de trouver les définitions plus rapidement et d'être compilé indépendamment.

Mais vous êtes maintenant confronté à un problème : ces fonctions ne peuvent plus être static au module, car static ne se réfère pas réellement à la module mais à la fichier source (unité de traduction). Vous êtes obligé de les rendre non static afin de pouvoir y accéder à partir d'autres parties (fichiers d'objets) de ce module. Mais cela signifie également qu'ils ne sont plus cachés/privés dans le module : ayant un lien externe, ils peuvent être accédés à partir d'autres modules, ce qui était le cas auparavant. pas votre intention initiale.

Sans nom 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.

Il serait bon de pouvoir spécifier que certains namespace est 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, le C++ ne dispose pas d'un tel concept de "modules", seulement d'"unités de traduction", qui sont étroitement liées aux fichiers source.

3 votes

Il s'agirait de toute façon d'un hack et d'une solution limitée, mais vous pourriez inclure le(s) fichier(s) cpp avec les fonctions internes statiques ou à espace de noms dans vos fichiers cpp "principaux". Ensuite, vous excluez ces fichiers cpp "satellites" de la compilation et vous avez terminé. Le seul problème est que si vous avez deux ou plusieurs fichiers cpp "principaux" et qu'ils veulent tous les deux utiliser cette fonction sympa d'un des fichiers cpp "satellites"...

0 votes

La solution n'est-elle pas d'utiliser l'héritage avec des fonctions privées/protégées/publiques avec des fonctions statiques ?

1 votes

Le C++20 introduit les modules, ce qui résout votre problème.

5voto

Salgar Points 4803

La norme C++ indique dans la section 7.3.1.1 Unnamed namespaces (espaces de noms sans nom), paragraphe 2 :

T dépréciée lors de la déclaration d'objets dans un l'espace de noms sans nom offre une alternative supérieure.

Static ne s'applique qu'aux noms d'objets, de fonctions et d'unions anonymes, et non aux déclarations de type.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X