Superioridade do namespace sem nome sobre estática?

129

Como os namespaces sem nome são superiores à staticpalavra - chave?

Nawaz
fonte
No entanto, os espaços para nome não nomeados não são um substituto suficiente para o espaço para nome estático , de acordo com o comitê de padrões. Ainda existem algumas instâncias em que os namespaces não nomeados falham e só staticfuncionam.
legends2k

Respostas:

133

Você está basicamente se referindo à seção §7.3.1.1 / 2 do C ++ 03 Standard,

O uso da palavra-chave estática é descontinuado ao declarar objetos em um escopo de espaço para nome; o espaço para nome sem nome fornece uma alternativa superior.

Observe que este parágrafo já foi removido no C ++ 11. staticfunções por padrão não são mais obsoletas!

No entanto, os espaços para nome sem nome são superiores à palavra-chave estática, principalmente porque a palavra-chave staticse aplica somente às declarações e funções das variáveis , não aos tipos definidos pelo usuário .

O código a seguir é válido em C ++

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

Mas esse código NÃO é válido:

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

Portanto, a solução é, namespace sem nome, que é esse,

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

Espero que isso explique por que unnamed-namespaceé superior a static.

Além disso, observe que o uso da palavra-chave estática foi descontinuado ao declarar objetos em um escopo de espaço para nome (conforme o Padrão).

Nawaz
fonte
11
De maneira mais geral, um espaço para nome sem nome permite ligação externa. É isso que habilita a declaração de classe local para unidade de tradução. Também permite, por exemplo, constante de cadeia de ligação externa, ser usada como argumento de modelo.
Saúde e hth. - Alf
10
Conforme observado por Fred Nurk em outra resposta, parece que essa deprecatedobservação foi removida do mais recente C ++ 0x FCD (n3225).
Matthieu M.
36
Você está respondendo sua própria pergunta e agradecendo a si mesmo: -o
manpreet singh
11
Qual seria a diferença de apenas definir a classe no cpp (sem espaço para nome anônimo, sem estática)?
Luchian Grigore 5/11
6
@LuchianGrigore Os problemas de vinculação no caso 2 .cppestão definindo uma classe com o mesmo nome.
Xaqq
8

Há um problema interessante relacionado a isso:

Suponha que você use a staticpalavra-chave ou sem nome namespacepara tornar alguma função interna do módulo (unidade de tradução), pois essa função deve ser usada internamente pelo módulo e não ser acessível fora dele. (Os sem nome namespacetêm a vantagem de tornar internas as definições de dados e tipos, além das funções).

Com o tempo, o arquivo de origem da implementação do seu módulo aumenta e você deseja dividi-lo em vários arquivos de origem separados, o que permitiria organizar melhor o código, encontrar as definições mais rapidamente e ser compilado independentemente.

Mas agora você enfrenta um problema: essas funções não podem mais ser staticdo módulo, porque staticna verdade não se referem ao módulo , mas ao arquivo de origem (unidade de tradução). Você é forçado a torná-las staticpara não permitir que elas sejam acessadas de outras partes (arquivos de objeto) desse módulo. Mas isso também significa que eles não estão mais ocultos / privados para o módulo: tendo ligação externa, eles podem ser acessados ​​a partir de outros módulos, o que não era sua intenção original.

O Unnamed namespacetambém não resolveria esse problema, porque também é definido para um arquivo de origem específico (unidade de tradução) e não pode ser acessado de fora.

Seria ótimo se alguém pudesse especificar que alguns namespacesão private, isto é, o que quer que seja definido nele, seja usado internamente pelo módulo ao qual ele pertence. Mas é claro que o C ++ não tem um conceito como "módulos", apenas "unidades de tradução", que estão fortemente vinculadas aos arquivos de origem.

SasQ
fonte
3
De qualquer forma, seria um hack e uma solução limitada, mas você pode incluir o (s) arquivo (s) cpp com as funções estáticas internas ou espaço para nome nos arquivos 'principais' do cpp. Em seguida, exclua esses arquivos cpp 'satellite' da compilação e pronto. O único problema se você tiver dois ou mais arquivos 'main' CPP e ambos querem usar essa função legal de um dos arquivos cpp 'satélites' ...
Sergey
não está usando herança com privado / protegido / público com funções estáticas a solução?
Ali
O C ++ 20 apresenta módulos, que resolvem seu problema.
LF
4

O Padrão C ++ lê na seção 7.3.1.1 Namespaces sem nome, parágrafo 2:

O uso da palavra-chave estática é preterido ao declarar objetos em um escopo de espaço para nome, o espaço para nome sem nome fornece uma alternativa superior.

Estático se aplica apenas a nomes de objetos, funções e uniões anônimas, não a declarações de tipo.

Salgar
fonte
5
Não, não faz. Um rascunho fez. E outro rascunho logo depois reverteu essa mudança boba.
Underscore_d