¿Superioridad del espacio de nombres sin nombre sobre el estático?

Respuestas:

134

Básicamente se refiere a la sección §7.3.1.1 / 2 del Estándar C ++ 03,

El uso de la palabra clave estática está en desuso cuando se declaran objetos en un ámbito de espacio de nombres; el espacio de nombres sin nombre proporciona una alternativa superior.

Tenga en cuenta que este párrafo ya se eliminó en C ++ 11. static¡las funciones son por estándar ya no están en desuso!

No obstante, los espacios de nombres sin nombre son superiores a la palabra clave estática, principalmente porque la palabra clave se staticaplica solo a las declaraciones y funciones de las variables , no a los tipos definidos por el usuario .

El siguiente código es válido en C ++

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

Pero este código NO es válido:

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

Entonces la solución es, unnamed-namespace, que es esto,

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

Espero que explique por qué unnamed-namespacees superior a static.

Además, tenga en cuenta que el uso de la palabra clave estática está en desuso cuando se declaran objetos en un ámbito de espacio de nombres (según el Estándar).

Nawaz
fuente
11
En términos más generales, un espacio de nombres sin nombre permite la vinculación externa. Eso es lo que habilita la declaración de clase de unidad local a unidad de traducción. También permite, por ejemplo, una cadena de vinculación externa constante, para ser utilizada como argumento de plantilla.
Saludos y hth. - Alf
10
Como señaló Fred Nurk en otra de sus respuestas, parece que este deprecatedcomentario se eliminó del último C ++ 0x FCD (n3225).
Matthieu M.
36
Estás respondiendo tu propia pregunta y
dándote las
12
¿Cuál sería la diferencia de solo definir la clase en el cpp (sin espacio de nombres anónimo, sin estática)?
Luchian Grigore
66
@LuchianGrigore Los problemas de vinculación en el caso 2 .cppestán definiendo una clase con el mismo nombre.
Xaqq
8

Hay un problema interesante relacionado con esto:

Suponga que usa una staticpalabra clave o sin nombre namespacepara hacer que alguna función sea interna al módulo (unidad de traducción), ya que esta función debe ser utilizada internamente por el módulo y no accesible fuera de él. (Los namespaces sin nombre tienen la ventaja de hacer que los datos y las definiciones de tipo también sean internas, además de las funciones).

Con el tiempo, el archivo fuente de la implementación de su módulo crece y le gustaría dividirlo en varios archivos fuente separados, lo que permitiría organizar mejor el código, encontrar las definiciones más rápido y compilarse de forma independiente.

Pero ahora enfrenta un problema: esas funciones ya no pueden estar staticen el módulo, porque en staticrealidad no se refiere al módulo , sino al archivo fuente (unidad de traducción). Usted está obligado a hacerlos no permitidos staticpara permitir el acceso desde otras partes (archivos de objetos) de ese módulo. Pero esto también significa que ya no están ocultos / privados para el módulo: al tener un enlace externo, se puede acceder desde otros módulos, lo cual no era su intención original.

Sin nombre namespacetampoco resolvería este problema, porque también se define para un archivo fuente particular (unidad de traducción) y no se puede acceder desde afuera.

Sería genial si uno pudiera especificar que alguno namespacees private, es decir, lo que esté definido en él, está destinado a ser utilizado internamente por el módulo al que pertenece. Pero, por supuesto, C ++ no tiene un concepto como "módulos", solo "unidades de traducción", que están estrechamente vinculadas a los archivos de origen.

SasQ
fuente
3
Sería un truco y una solución limitada de todos modos, pero podría incluir los archivos cpp con las funciones internas estáticas o de espacio de nombres en sus archivos cpp 'principales'. Luego excluya estos archivos cpp 'satélite' de la compilación y ya está. El único problema si tiene dos o más archivos cpp 'principales' y ambos quieren usar esa función genial de uno de los archivos cpp 'satélite' ...
Sergey
¿No está utilizando la herencia con privado / protegido / público con funciones estáticas la solución?
Ali
C ++ 20 presenta módulos, lo que resuelve su problema.
LF
4

El estándar C ++ se lee en la sección 7.3.1.1 Espacios de nombres sin nombre, párrafo 2:

El uso de la palabra clave estática está en desuso cuando se declaran objetos en un ámbito de espacio de nombres, el espacio de nombres sin nombre proporciona una alternativa superior.

Estático solo se aplica a nombres de objetos, funciones y uniones anónimas, no a declaraciones de tipo.

Salgar
fuente
55
No lo hace Un borrador lo hizo. Y otro borrador muy poco después de eso revirtió este tonto cambio.
underscore_d