2010-03-25 6 views
4

J'ai un espace de noms avec une tonne de symboles que j'utilise, mais je veux remplacer l'un d'eux:Résoudre les conflits namespace

external_library.h

namespace LottaStuff 
{ 
class LotsOfClasses {}; 
class OneMoreClass {}; 
}; 

my_file.h

using namespace LottaStuff; 
namespace MyCustomizations 
{ 
class OneMoreClass {}; 
}; 
using MyCustomizations::OneMoreClass; 

my_file.cpp

int main() 
{ 
    OneMoreClass foo; // error: reference to 'OneMoreClass' is ambiguous 
    return 0; 
} 

Comment résoudre l'erreur "ambiguë" sans avoir à remplacer "using namespace LottaStuff" par un millier "using xxx;" déclarations? Editer: Aussi, disons que je ne peux pas éditer my_file.cpp, seulement mon_fichier.h. Donc, remplacer OneMoreClass par MyCustomizations :: OneMoreClass partout comme suggéré ci-dessous ne serait pas possible.

+2

Voici un conseil - N'utilisez PAS le mot-clé "using" mais faites plutôt référence aux classes avec leurs noms complets: vector <> -> :: std :: vector <>! – Poni

+0

C++ 11 aura une bonne fonctionnalité pour la gestion des espaces de noms (en-ligne) qui permettra à l'utilisateur d'obtenir exactement ceci ... alors encore une fois, vous devrez attendre plus que vous voulez que la fonctionnalité soit dans votre compilateur sauf si vous utilisez gcc> 4.4) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2535.htm –

+0

Voir aussi [Comment utiliser correctement les espaces de noms en C++?] (https://stackoverflow.com/questions/41590/how-do-you-properly-use-namespaces-in-c) – Vadzim

Répondre

8

est vaincu le point de namespaces entier quand vous dites "using namespace".

Alors sortez-le et utilisez les espaces de noms. Si vous voulez une directive à l'aide, le mettre dans le principal:

int main() 
{ 
    using myCustomizations::OneMoreClass; 

    // OneMoreClass unambiguously refers 
    // to the myCustomizations variant 
} 

Comprendre ce que using directives font. Ce que vous avez est essentiellement ceci:

namespace foo 
{ 
    struct baz{}; 
} 

namespace bar 
{ 
    struct baz{}; 
} 

using namespace foo; // take *everything* in foo and make it usable in this scope 
using bar::baz; // take baz from bar and make it usable in this scope 

int main() 
{ 
    baz x; // no baz in this scope, check global... oh crap! 
} 

L'un ou l'autre fonctionnera, ainsi que de placer un dans le cadre de main. Si vous trouvez un espace de noms vraiment fastidieux type, faire un alias:

namespace ez = manthisisacrappilynamednamespace; 

ez::... 

Mais jamais utilisation using namespace dans un en-tête, et probablement jamais portée mondiale. C'est bien dans les portées locales.

3

Vous devez explicitement spécifier les OneMoreClass que vous voulez:

int main() 
{ 
    myCustomizations::OneMoreClass foo; 
} 
+0

Et si je n'arrive pas à éditer my_file.cpp? édité ma question ci-dessus. – Kyle

+3

@Kyle: Puis arrêtez d'utiliser 'using namespace'. Vous ne pouvez pas utiliser cela alors se plaindre des conflits d'espace de noms. C'est comme si vous aviez des ceintures de sécurité dans votre voiture, mais vous les arrachez et vous vous dites que vous n'êtes pas en sécurité. – GManNickG

Questions connexes