2008-10-03 4 views
64

Un des caprices de mon système de développement (CodeGear C++ Builder) est que certains des en-têtes générés automatiquement insistez pour avoir ...Comment puis-je "désutiliser" un espace de noms?

using namespace xyzzy 

... déclarations en eux, qui ont un impact sur mon code quand je le veux le moins ou attendez-le.

Y at-il un moyen que je puisse annuler/remplacer d'une manière ou d'une autre une instruction "using" précédente pour éviter cela.

... Peut-être

unusing namespace xyzzy; 
+2

Vous devriez probablement ouvrir un rapport de bogue avec leur système QC: http://qc.codegear.com/ –

+1

BTW, quels en-têtes générés automatiquement sont-ils? –

+0

Un jour, C++ aura des modules, et inclure du code dans un autre code aura de meilleures constructions d'encapsulation. Jusque-là, il n'y a pas un moyen facile de contourner cela. Pensez à mettre votre propre code dans un espace de noms et à y faire référence de cette façon. –

Répondre

45

Non, mais il y a une solution potentielle. si vous entourez votre directive include dans un espace propre, comme celui-ci ...

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

... alors les effets de toute directive d'utilisation dans cet en-tête sont neutralisés.

Cela peut être problématique dans certains cas. C'est pourquoi chaque guide de style C++ recommande fortement et non en insérant une directive "using namespace" dans un fichier d'en-tête.

+0

En général, il s'agit d'une idée _terrible_. Les en-têtes C++ ne sont pas destinés à être inclus dans un espace de noms alternatif comme cela a été utilisé ici. – Aaron

+17

C'est une mauvaise idée d'inclure une directive using dans un fichier d'en-tête aussi. Cela atténue simplement ce problème. –

+3

Le fait de placer l'en-tête dans votre propre espace de noms n'est pas une solution car il modifie la signification des déclarations dans cette bibliothèque. (-1) –

37

Non, vous ne pouvez pas unuse un espace de noms. La seule chose que vous pouvez faire est de mettre un using namespace -statement dans un bloc pour limiter sa portée.

Exemple:

{ 
    using namespace xyzzy; 

} // stop using namespace xyzzy here 

Peut-être que vous pouvez changer le modèle qui est utilisé de vos têtes générés automatiquement.

+0

Pouvez-vous emballer une inclusion dans un bloc comme celui-ci si? – Eclipse

+0

Oui, ce ne sera pas avec le code généré automatiquement. Byt mybe peut-il changer le template pour le code généré automatiquement? –

+0

Oui, cela ne résout pas vraiment le problème qu'il a des en-têtes utilisant des espaces de noms. – Kip

1

Une expérience rapide avec Visual Studio 2005 montre que vous pouvez inclure ces en-têtes dans votre propre espace de nommage, puis use ce dont vous avez besoin de cet espace de noms (mais pas use l'espace de noms complet, car il introduit l'espace de noms cacher

+1

Cela provoquera probablement des problèmes de dénaturation si les fichiers d'en-tête sont des déclarations pour une bibliothèque. La compilation réussira, mais l'éditeur de liens ne pourra pas trouver les définitions, car elles auraient déjà été compilées dans un espace de noms différent. – Eclipse

12

vous pouvez être coincé en utilisant les espaces de noms explicites sur les conflits.

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 
7

Que diriez-vous d'utiliser sed, perl ou un autre outil de ligne de commande dans le cadre de votre processus de construction pour modifier les en-têtes générés après qu'ils soient générés mais avant qu'ils ne soient utilisés?

+0

Dans le cas où il existe de nombreux en-têtes, cela peut être trop lent – doc

+3

sed plus lent que le générateur de code? Difficile à croire ... – Arkadiy

8

Pour référence future: depuis la version XE il y a une nouvelle valeur que vous pouvez #define pour éviter la using namespace System; redoutée int comprennent: DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE

+3

Bien, merci. Peut-être que je n'aurais pas dû annuler SA après tout ... – Roddy

+0

Mais cela ne semble pas fonctionner correctement. Au moins dans tous les cas j'ai essayé (avec BCB6). Je me suis ensuite rabattue sur l'ajout d'espaces de noms explicites sur les conflits et, pire encore, j'inclus un en-tête pour éviter les conflits de noms de types ... – Wolf

-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); 
} 
+0

veuillez expliquer votre réponse! – Mazz

+0

vous pouvez utiliser l'opérateur de résolution d'étendue pour utiliser une autre variable d'espace de noms –

+1

Ne répond pas à la question –

Questions connexes