Sin embargo, los espacios de nombres sin nombre no son un reemplazo suficiente para el espacio de nombres estático , según el comité de estándares. Todavía hay algunas instancias donde los espacios de nombres sin nombre fallan y solo staticfuncionan.
legends2k
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 codestaticint sample_function(){/* function body */}staticint sample_variable;
Pero este código NO es válido:
//illegal codestaticclass sample_class {/* class body */};staticstruct sample_struct {/* struct body */};
Entonces la solución es, unnamed-namespace, que es esto,
//legal codenamespace{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).
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.
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.
static
funcionan.Respuestas:
Básicamente se refiere a la sección §7.3.1.1 / 2 del Estándar C ++ 03,
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
static
aplica 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 ++
Pero este código NO es válido:
Entonces la solución es, unnamed-namespace, que es esto,
Espero que explique por qué
unnamed-namespace
es superior astatic
.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).fuente
deprecated
comentario se eliminó del último C ++ 0x FCD (n3225)..cpp
están definiendo una clase con el mismo nombre.Hay un problema interesante relacionado con esto:
Suponga que usa una
static
palabra clave o sin nombrenamespace
para 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. (Losnamespace
s 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
static
en el módulo, porque enstatic
realidad no se refiere al módulo , sino al archivo fuente (unidad de traducción). Usted está obligado a hacerlos no permitidosstatic
para 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
namespace
tampoco 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
namespace
esprivate
, 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.fuente
El estándar C ++ se lee en la sección 7.3.1.1 Espacios de nombres sin nombre, párrafo 2:
Estático solo se aplica a nombres de objetos, funciones y uniones anónimas, no a declaraciones de tipo.
fuente