2010-01-28 4 views
29

Con using namespace hago que todo el contenido de ese espacio de nombres sea visible directamente sin utilizar el calificador del espacio de nombres. Esto puede causar problemas si using namespace aparece en encabezados ampliamente utilizados: podemos hacer inintencionadamente dos espacios de nombres con nombres de clases idénticos visibles y el compilador se negará a compilar a menos que el nombre de clase se anteponga con el calificador del espacio de nombres.¿Puedo deshacer el efecto de "usar el espacio de nombres" en C++?

¿Puedo deshacer using namespace para que el compilador olvide que lo vio anteriormente?

+0

Apuesto a que hay un corte muy feo utilizando el procesador previo para esto. Pero supongo que no quiere eso –

+6

@Eli: No hay en Boost, lo que probablemente significa que no hay uno. –

+0

Una posible solución para al menos acortar lo que debe escribir sería ''definir N namespace ::' en la parte superior de un archivo y '#undef N' en la parte inferior. Por supuesto, esto significa que debe tener cuidado de no utilizar 'N' en ningún lugar del archivo que no desee que sea' namespace :: '. Un 'typedef' podría ser potencialmente útil también. – Yay295

Respuesta

35

No, pero puede decirle a sus compañeros de trabajo que nunca debe tener una directiva o declaración using en un encabezado.

3

Que yo sepa ... Pero como regla, solo uso "usar el espacio de nombres" en los archivos .cpp.

15

Como han dicho otros, no se puede y el problema no debería estar allí en primer lugar.
El siguiente mejor cosa que puede hacer es traer a sus símbolos necesarios para que ellos son los preferidos por el nombre de consulta:

namespace A { class C {}; } 
namespace B { class C {}; } 
using namespace A; 
using namespace B; 

namespace D { 
    using A::C; // fixes ambiguity 
    C c; 
} 

En algunos casos también se puede envolver el infractor incluye con un espacio de nombres:

namespace offender { 
# include "offender.h" 
} 
+7

Esa última técnica puede ser una lata de gusanos. Si el delincuente.h incluye encabezados que están protegidos con '# define', ahora esos símbolos están atrapados en el delincuente. Podría tratar de poner todo su paquete de interfaz de manera exhaustiva en un nuevo espacio de nombres, pero aún así esperar que no incluya los encabezados del sistema. Y si funciona una vez, podría romperse en la próxima versión. – Potatoswatter

+2

Por lo tanto * en algunos casos *. –

6

No, C++ Standard no dice nada sobre "deshacer". Lo mejor que se les permite hacer es limitar el alcance de using:

#include <vector> 

namespace Ximpl { 

using namespace std;  
vector<int> x; 

} 

vector<int> z; // error. should be std::vector<int> 

Pero, por desgracia using namespace Ximpl traerá todos los nombres de espacio de nombres std también.

0

Lo más cerca que voy a tratar de utilizar en los archivos de cabecera es el siguiente:

//example.h 

#ifndef EXAMPLE_H_ 
#define EXAMPLE_H_ 


/** 
* hating c++ for not having "undo" of using namespace xx 
*/ 
#define string std::string 
#define map std::map 

class Example { 
public: 
    Example (const char *filename); 
    Example (string filename); 
    ~Example(); 
private: 
    map<string,complicated_stuff*> my_complicated_map; 

}; 

#undef string 
#undef map 

#endif //EXAMPLE_H_ 

después de todo, son #undef define -able. Hay 2 problemas: 1. es feo 2. #define y #undef separado para cada nombre del espacio de nombres correspondiente se utilizan

Cuestiones relacionadas