2008-12-10 11 views
34

Alguien afirmó hoy en SO que nunca debe usar espacios de nombres anónimos en archivos de encabezado. Normalmente esto es correcto, pero parece recordar que una vez alguien me dijo que una de las bibliotecas estándar usa espacios de nombres anónimos en archivos de encabezado para realizar algún tipo de inicialización.Usos para espacios de nombres anónimos en archivos de encabezado

¿Lo recuerdo correctamente? ¿Alguien puede completar los detalles?

+1

Ver esta discusión: [http://stackoverflow.com/questions/357404/anonynous-namespaces](http://stackoverflow.com/questions/357404/anonynous-namespaces) –

+0

eso es el hilo donde ha obtenido esa información de espacios de nombres anónimos en los encabezados es malo –

+0

No encuentro nada en ese hilo sobre su uso en los archivos de encabezado. ¿Alguien puede explicar por qué esto está mal? ¿Y todavía se aplica en C++ 11? – baruch

Respuesta

20

La única situación en la que un espacio de nombres sin nombre en la cabecera puede ser útil es cuando se desea distribuir el código como los archivos de cabecera solamente. Por ejemplo, un gran subconjunto independiente de Boost es puramente encabezados.

El token ignore para tuplas, mencionado en otra respuesta es un ejemplo, el _1, _2 etc. vinculan marcadores de posición son otros.

+0

creo que has hecho un buen punto con esto. –

+0

No debe usar el espacio de nombres anónimo para esto, ya que todos se colapsaron juntos en la unidad de compilación final y pueden ocasionar conflictos de espacio de nombres. En su lugar, use un nombre que, por convención, signifique que los contenidos son detalles de implementación. Boost, por ejemplo, usa 'detail'. – thehouse

+0

@thehouse Parece que no entendió cómo Boost utiliza los espacios de nombres anónimos. 'ignore' y' _1', '_2' etc. son símbolos públicos, no pertenecen a' detail'. Pero acepto que un espacio de nombres de detalles es normalmente la elección correcta para el equivalente de un espacio de nombres anónimo de una biblioteca de encabezado. –

2

Realmente no puedo ver ningún beneficio positivo del uso de espacios de nombres anónimos en los encabezados. La confusión que puede resultar de tener la misma declaración de símbolo significa, en esencia, una cosa diferente en las unidades de compilación que incluyen ese encabezado sería una manera garantizada de ir prematuramente y dolorosamente calvo.

0

Si es la inicialización, es probable que sea un encabezado iostream s (como istream, ios, etc.).

13

No veo ningún sentido al poner un espacio de nombre anónimo en un archivo de encabezado. He grepped las cabeceras del libstdC++ estándar y, no encontró espacios de nombres anónimos, aparte de uno en la cabecera tuple (C++ 1x cosas):

// A class (and instance) which can be used in 'tie' when an element 
    // of a tuple is not required 
    struct _Swallow_assign 
    { 
    template<class _Tp> 
     _Swallow_assign& 
     operator=(const _Tp&) 
     { return *this; } 
    }; 

    // TODO: Put this in some kind of shared file. 
    namespace 
    { 
    _Swallow_assign ignore; 
    }; // anonymous namespace 

Esto es lo que puede hacer

std::tie(a, std::ignore, b) = some_tuple; 

a los elementos del some_tuple se les asignan las variables en el lado izquierdo (ver here), se usa una técnica similar para el iterador this. El segundo elemento es ignorado.

Pero como dicen, debe colocarse en un archivo .cpp y la instancia debe ser compartida por todos los usuarios. Ellos pusieron una declaración de que en la cabecera como esta a continuación:

extern _Swallow_assign ignore; 
+0

C++ 1x? ¿Me he perdido algo? –

+0

siguiente versión de C++ –

+0

Sutter todavía lo llama C++ 0x (http://herbsutter.wordpress.com/2008/10/28/september-2008-iso-c-standards-meeting-the-draft-has-landed -and-a-new-convener /). –

4

Lo he visto utilizado para proporcionar un valor predeterminado para una variable en diferentes unidades de traducción. Pero podría causar un comportamiento inesperado en el caso de los conflictos de nombres.

Ejemplo

a.hpp

namespace 
{ 
    const char name[] = "default"; 
} 
// This macro will hide the anonymous variable "name" 
#define SET_NAME(newname) \ 
static const char name[] = newname; 

b.cpp

#include "a.hpp" 
SET_NAME("file b") // name is "file b" in this translation unit 

c.cpp

#include "a.hpp" 
SET_NAME("file c") // name is "file c" in this translation unit 

d.cpp

#include "a.hpp" 
// name is "default" in this translation unit 

correo.CPP

#include "a.hpp" 
static const char name[] = "unintended"; 
// accidently hiding anonymous name 
Cuestiones relacionadas