2010-01-28 9 views
29

Con using namespace Rendo visibile l'intero contenuto di tale spazio dei nomi senza utilizzare il qualificatore di spazio dei nomi. Ciò può causare problemi se using namespace si verifica in intestazioni ampiamente utilizzate - possiamo rendere involontariamente due spazi dei nomi con nomi di classi identiche visibili e il compilatore rifiuterà di compilare a meno che il nome della classe non sia anteposto al qualificatore di namespace.Posso annullare l'effetto di "using namespace" in C++?

Posso annullare using namespace in modo che il compilatore dimentichi di averlo visto in precedenza?

+0

Scommetto che c'è davvero un brutto hack utilizzando il pre-processore per questo. Ma immagino che tu non voglia quello –

+6

@Eli: Non c'è in Boost, il che probabilmente significa che non ce n'è uno. –

+0

Una possibile soluzione per accorciare almeno ciò che è necessario digitare sarebbe '#define N namespace ::' nella parte superiore di un file e '#undef N' nella parte inferiore. Ovviamente questo significa che devi stare attento a non usare mai 'N' ovunque nel file che non vuoi' namespace :: '. Un 'typedef' potrebbe anche essere utile. – Yay295

risposta

35

No, ma puoi dire ai tuoi colleghi che non dovresti mai avere una direttiva using o una dichiarazione in un'intestazione.

3

Non a mia conoscenza ... Ma di regola uso solo "using namespace" nei file .cpp.

15

Come altri hanno detto, non è possibile e il problema non dovrebbe essere lì in primo luogo.
La prossima cosa migliore che puoi fare è di portare nei vostri simboli necessari in modo che essi sono preferiti dal nome di look-up:

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

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

In alcuni casi si può anche avvolgere l'incriminato include con uno spazio dei nomi:

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

Quest'ultima tecnica può essere una lattina di vermi. Se offender.h include le intestazioni che sono '# define' protette, ora quei simboli sono bloccati nell'offensore. Potresti provare a inserire l'intero pacchetto dell'interfaccia in un nuovo spazio dei nomi, ma spero comunque che non includa le intestazioni di sistema. E se funziona una volta, potrebbe rompersi nella prossima versione. – Potatoswatter

+2

Così * in alcuni casi *. –

6

No, lo standard C++ non dice nulla su "annulla". Il meglio che si è permesso di fare è quello di limitare la portata di using:

#include <vector> 

namespace Ximpl { 

using namespace std;  
vector<int> x; 

} 

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

Ma purtroppo using namespace Ximpl porterà tutti i nomi da std spazio dei nomi pure.

0

Il più vicino, che cercherò di utilizzare nei file di intestazione è la seguente:

//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_ 

dopo tutto, definisce sono #undef -abile. Ci sono 2 problemi: 1. è brutto 2. #define e #undef diverse per ciascun nome dal corrispondente namespace sono utilizzati