583 votes

Espaces de noms sans nom/anonyme vs fonctions statiques

Un peu utilisé la fonctionnalité de C++ est la possibilité de créer sans nom (anonyme) des espaces de noms, comme suit:

namespace {
    int cannotAccessOutsideThisFile() { ... }
} // namespace

On pourrait penser qu'une telle fonctionnalité serait inutile, puisque vous ne pouvez pas spécifier le nom de l'espace de noms, il est impossible d'accéder à quoi que ce soit dans de l'extérieur. Mais ces espaces de noms sans nom sont accessibles dans le fichier, elles sont créées, comme si vous aviez un implicite à l'aide de la clause.

Ma question est, pourquoi et quand cela serait-il préférable à l'utilisation des fonctions statiques? Ou sont-ils essentiellement deux façons de faire exactement la même chose?

378voto

luke Points 16255

La Norme C++ lit dans la section 7.3.1.1 sans nom les espaces de noms, paragraphe 2:

L'utilisation du mot-clé static est obsolète lors de la déclaration d'objets dans un espace de noms de champ, sans nom d'espace de noms offre une meilleure alternative.

Statique s'applique uniquement aux noms des objets, des fonctions et des syndicats, de ne pas les déclarations de type.

Edit:

La décision de rendre caduque cette utilisation du mot-clé static (affecter la visibilité d'une déclaration de variable dans une unité de traduction) a été inversé (ref). Dans ce cas, à l'aide d'un statique ou sans nom d'espace de noms sont de retour à être essentiellement deux façons de faire exactement la même chose. Pour plus de détails, veuillez voir cette SORTE de question.

Sans nom les espaces de noms ont encore l'avantage de vous permettre de définir la traduction-unité-types locaux. Veuillez voir ce DONC, la question pour plus de détails.

Le crédit va à Mike Percy pour avoir porté à mon attention.

82voto

hazzen Points 7315

Mettre les méthodes dans un espace de noms anonyme vous empêche de violer accidentellement l' Une règle de définition, vous permettant de vous inquiétez jamais nommer vos méthodes d’assistance identique à une autre méthode, dans que vous pouvez créer un lien.

Et, comme indiqué par luke, espaces de noms anonymes sont préférés par la norme sur les membres statiques.

39voto

Richard Corden Points 12292

Il est un cas limite où statique a une surprenante touche (au moins c'était pour moi). Le C++03 Standard unis dans 14.6.4.2/1:

Pour un appel de fonction qui dépend d'un paramètre du modèle, si le nom de la fonction est un unqualified-id , mais pas un modèle-id, le candidat fonctions sont trouvés à l'aide de l'habitude, les règles de recherche (3.4.1, 3.4.2), sauf que:

  • Pour la partie de la recherche de l'aide inconditionnelle de recherche de nom (3.4.1), seules les déclarations de fonction avec une liaison externe à partir de la définition de modèle de contexte sont trouvés.
  • Pour la partie de la recherche de l'aide associée à des espaces de noms (3.4.2), seules les déclarations de fonction avec une liaison externe trouvée dans la tmeplate définition du contexte ou de l'instanciation du modèle de contexte sont trouvés.

...

Le code ci-dessous appellera foo(void*) et pas foo(S const &) comme vous vous en doutez.

template <typename T>
int b1 (T const & t)
{
  foo(t);
}

namespace NS
{
  namespace
  {
    struct S
    {
    public:
      operator void * () const;
    };

    void foo (void*);
    static void foo (S const &);   // Not considered 14.6.4.2(b1)
  }

}

void b2()
{
  NS::S s;
  b1 (s);
}

En soi, ce n'est probablement pas un gros problème, mais elle met en évidence que, pour un entièrement conforme compilateur C++ (c'est à dire. celui avec le soutien de export) static mot clé sera toujours avoir une fonctionnalité qui n'est pas disponible de toute autre manière.

// bar.h
export template <typename T>
int b1 (T const & t);

// bar.cc
#include "bar.h"
template <typename T>
int b1 (T const & t)
{
  foo(t);
}

// foo.cc
#include "bar.h"
namespace NS
{
  namespace
  {
    struct S
    {
    };

    void foo (S const & s);  // Will be found by different TU 'bar.cc'
  }
}

void b2()
{
  NS::S s;
  b1 (s);
}

La seule façon de s'assurer que la fonction de notre sans nom d'espace de noms ne seront pas trouvés dans les modèles à l'aide de l'ADL est de rendre l' static.

7voto

Firas Assaad Points 10339

Utilisation du mot clé static à cet effet est désapprouvée par la norme C ++98. Le problème avec statique, c’est qu’il ne s’applique pas à la définition de type. C’est également un mot-clé surchargé utilisé de différentes manières dans des contextes différents, donc des espaces de noms sans nom simplifient un peu les choses.

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