¿Cómo puedo "desutilizar" un espacio de nombres?

86

Uno de los caprichos de mi sistema de desarrollo (Codegear C ++ Builder) es que algunos de los encabezados generados automáticamente insisten en tener ...

using namespace xyzzy

... declaraciones en ellos, que impactan en mi código cuando menos lo deseo o lo espero.

¿Hay alguna manera de que de alguna manera pueda cancelar / anular una declaración anterior de "uso" para evitar esto?

Tal vez...

unusing namespace xyzzy;
Roddy
fuente
3
Probablemente debería abrir un informe de error con su sistema de control de
Kris Kumler
2
Por cierto, ¿qué encabezados generados automáticamente son estos?
Kris Kumler
2
Algún día, C ++ tendrá módulos, e incluir código en otro código tendrá mejores construcciones de encapsulación. Hasta entonces, no hay una manera fácil de evitar esto. Considere poner su propio código en un espacio de nombres y referirse a él de esa manera.
Trevor Hickey

Respuestas:

59

No Pero hay una solución potencial: si adjunta su directiva include en un espacio de nombres propio, como este ...

namespace codegear {
    #include "codegear_header.h"
} // namespace codegear

... entonces se neutralizan los efectos de cualquier directiva using dentro de ese encabezado.

Eso puede resultar problemático en algunos casos. Es por eso que cada guía de estilo de C ++ recomienda encarecidamente no poner una directiva de "uso de espacio de nombres" en un archivo de encabezado.

Jefe Geek
fuente
1
En general, esta es una idea terrible . Los encabezados de C ++ no están destinados a incluirse en un espacio de nombres alternativo como se usó aquí.
Aaron
24
También es una idea terrible incluir una directiva using en un archivo de encabezado. Esto simplemente mitiga ese problema.
Head Geek
4
Colocar el encabezado en su propio espacio de nombres no es una solución, ya que cambia el significado de las declaraciones en esa biblioteca. (-1)
Richard Corden
4
Eso depende completamente de lo que se declare en el encabezado.
Head Geek
1
Precisamente por eso es un comportamiento indefinido.
Kris Kumler
56

No, no puede deshacer el uso de un espacio de nombres. Lo único que puede hacer es using namespacebloquear la declaración -enunciado para limitar su alcance.

Ejemplo:

{
    using namespace xyzzy;

} // stop using namespace xyzzy here

Tal vez pueda cambiar la plantilla que se utiliza en sus encabezados generados automáticamente.

jk.
fuente
Sin embargo, ¿puedes envolver una inclusión en un bloque como este?
Eclipse
Sí, esto no ocurrirá con el código generado automáticamente. Por cierto, ¿puede cambiar la plantilla del código generado automáticamente?
jk.
Sí, esto realmente no soluciona el problema que tiene de los encabezados que usan espacios de nombres.
Kip
Desafortunadamente, esto no es verdad. Prueba esto:
Adam
espacio de nombres xyzzy {const int i {usando el espacio de nombres xyzzy; } // dejar de usar el espacio de nombres xyzzy aquí
Adam
17

Es posible que se quede atascado al usar espacios de nombres explícitos en conflictos:

string x; // Doesn't work due to conflicting declarations
::string y; // use the class from the global namespace
std::string z; // use the string class from the std namespace
Eclipse
fuente
10

Para referencia futura: desde la versión XE hay un nuevo valor que puede # definir para evitar el temido using namespace System;int el include: DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE

cdelacroix
fuente
Pero esto parece no funcionar correctamente. Al menos en todos los casos lo intenté (con BCB6). Luego solía recurrir a agregar espacios de nombres explícitos en los conflictos y, lo que es peor, incluir un encabezado para evitar conflictos de nombres de tipos ...
Wolf
6

¿Qué tal usar sed, perl o alguna otra herramienta de línea de comandos como parte de su proceso de compilación para modificar los encabezados generados después de que se generen pero antes de que se utilicen?


fuente
1

Un experimento rápido con Visual Studio 2005 muestra que puede incluir esos encabezados en su propio espacio de nombres con nombre y luego uselo que necesita de este espacio de nombres (pero no en usetodo el espacio de nombres, ya que presentará el espacio de nombres que desea ocultar.

Kasprzol
fuente
1
Es probable que esto cause problemas de alteración de nombres si los archivos de encabezado son declaraciones para una biblioteca. La compilación se realizará correctamente, pero el vinculador no podrá encontrar las definiciones, ya que ya se habrían compilado en un espacio de nombres diferente.
Eclipse
-1
#include<iostream>
#include<stdio.h>
namespace namespace1 {
    int t = 10;
}
namespace namespace2 {
    int t = 20;
}
int main() {
using namespace namespace1;
    printf("%d" , t);
    printf("%d" , namespace2::t);
}
Narendra kumawat
fuente
1
por favor explique su respuesta!
Mazz
puede usar el operador de resolución de alcance para usar otra variable de espacio de nombres
Narendra kumawat
3
No aborda la pregunta
MM