blindage #inclure, à l'intérieur de l'espace de noms { } bloc?
Edit: je sais que la méthode 1 est essentiellement non valide et ne sera probablement utiliser la méthode 2, mais je suis à la recherche pour le meilleur hack ou une meilleure solution pour atténuer rampant, mutable espace de noms de la prolifération.
Je plusieurs la classe ou la méthode définitions dans un espace de noms différent de dépendances, et souhaitez utiliser le moins d'espace de noms de blocs ou explicite scopings possible, mais alors que le groupement des directives #include avec les définitions qui nécessitent du mieux que possible. Je n'ai jamais vu aucune indication que toute préprocesseur pourrait être dit à exclure de l'espace de noms {} la portée de #inclure du contenu, mais je suis ici pour vous demander si quelque chose de semblable à cela est possible: (voir en bas pour l'explication de pourquoi je veux quelque chose de simple morts)
//NOTE: apple.h, etc., contents are *NOT* intended to be in namespace Foo!
//would prefer something most this:
#pragma magic_namespace_backout(1) //FIXME: use actually existing directive
namespace Foo {
#include "apple.h"
B *A::blah(B const *x) { /* ... */ }
#include "banana.h"
int B::whatever(C const &var) { /* ... */ }
#include "blueberry.h"
void B::something() { /* ... */ }
} //namespace Foo
...
//over this:
#include "apple.h"
#include "banana.h"
#include "blueberry.h"
namespace Foo {
B *A::blah(B const *x) { /* ... */ }
int B::whatever(C const &var) { /* ... */ }
void B::something() { /* ... */ }
} //namespace Foo
...
//or over this:
#include "apple.h"
namespace Foo {
B *A::blah(B const *x) { /* ... */ }
} //namespace Foo
#include "banana.h"
namespace Foo {
int B::whatever(C const &var) { /* ... */ }
} //namespace Foo
#include "blueberry.h"
namespace Foo {
void B::something() { /* ... */ }
} //namespace Foo
Mon vrai problème, c'est que j'ai des projets dans lesquels un module peut avoir besoin d'être ramifiés, mais ont la coexistence des composants à partir des branches dans le même programme. J'ai des classes comme FooA, etc., que j'ai appelé Foo::dans l'espoir d'être en mesure de branche de moins en moins douloureusement que Foo::v1_2::A, où un programme peut avoir besoin à la fois d'un Foo::Un et un Foo::v1_2::A. je voudrais "Toto" ou "Foo::v1_2" pour montrer jusqu'n'est vraiment qu'une seule fois par fichier, comme un espace de noms unique bloc, si possible. De plus, j'ai tendance à préférer pour localiser les blocs de directives #include, immédiatement au-dessus de la première définition dans le fichier qui les exige. Quel est mon meilleur choix, ou sinon, que dois-je faire à la place de détourner les espaces de noms?
OriginalL'auteur Jeff | 2010-05-19
Vous devez vous connecter pour publier un commentaire.
Il suffit de penser de #y compris en tant que de copier et de coller le contenu du fichier inclus à la position de la directive #include.
Cela signifie que, oui, tout est dans le fichier inclus, sera à l'intérieur de l'espace de noms.
À noter que toute
#define
s ne sera pas à l'intérieur de l'espace de noms.Depuis
#define
s n'ont pas la notion d'espace de noms que ce soitOriginalL'auteur Timbo
Q: Pouvez-vous:
R: Oui, vous pouvez. La déclaration est effectuée au cours de pré-traitement avant le compilateur voit même les.
Q: Est-ce une bonne idée.
R: Probablement pas.
Ce qui se passe si vous #include Apple.g sans l'espace de noms de balises.
maintenant, vous avez les pommes déclarés dans l'espace de noms global que-eh bien, comme les foo espace de noms.
Vous devriez essayer d'éviter les situations où vous, l'utilisateur de votre code doit comprendre comment il doit être utilisé. Si votre documentation dit toujours #inclure l'apple fichier d'en-tête à l'intérieur de la foo espace de noms est le bit de l'utilisateur ne sera pas lu et causer des heures de confusion.
namespace Foo { #include apple_noNS.h }
ensuite, y compris apple.h partout en dehors de l'espace de noms.C'est une idée terrible. Et explicitement couverts par la déclaration ci-dessus pourquoi.
Dans ma situation, la structure de données est partagée entre un (petit) C ANSI programme, et une (vaste) programme en C++. Il n'y a pas d'espaces de noms en C, mais en raison de la C la taille du programme, les risques de conflits et les problèmes de ses nombreuses entrées existantes dans l'espace de noms global sont atténués. Otoh, que, y compris dans l'espace de noms global de l'application C++ serait la cause d'une foule de problèmes. L'utilisateur de mon code doit comprendre que la dépendance de toute façon, ou les choses vont souffler dans leur visage si elles ne C++ choses avec le C pièces. Ces fichiers doivent être considérés comme des champs privés de la classe de l'API.
Cela ne change rien. Il y a toujours de meilleures façons de le faire. Comme indiqué ci-dessus (et répétée à maintenant), cela va entraîner des problèmes. Si vous voulez trouver une meilleure façon de le faire, puis poser une question et nous vous fournirons la façon correcte de le faire.
"Vous devriez essayer et d'éviter les situations où vous, l'utilisateur de votre code doit comprendre comment il doit être utilisé." c'est probablement la meilleure ligne directrice jamais 🙂
OriginalL'auteur Martin York
Apprendre à aimer le troisième exemple, en les divisant en trois fichiers distincts. Que serais vraiment la façon la plus claire d'aller.
Si vous voulez vraiment pour inclure des fichiers à l'intérieur d'autres espaces de noms, vous pouvez mettre
}
que le premier caractère du fichier include etnamespace Whatever {
à la fin. Mais ce serait terrible.OriginalL'auteur dash-tom-bang
Avez-vous modifier cette question?
Le premier bloc dans votre exemple n'est pas possible. Vous ne pouvez pas aller jusqu'à un espace de noms ou que ce soit de l'intérieur de l'un comme vous voulez et vous ne pouvez pas désactiver l'espace de noms dans un fichier inclus dans l'espace de nom du bloc. Il ne peut simplement pas être fait de cette manière.
Personnellement je préfère la première de vos solutions de rechange.
Edit, ok...voici quelque chose que vous pourriez faire (peut-être besoin de nettoyage, non testé):
Assez sûr NAMESPACE_WRAP de ne pas travailler pour ce genre de chose, mais vous aurez probablement besoin de le mettre dans un en-tête ou ".ipp" ou quoi que ce soit et ce faire:
Même qui ne fonctionne pas et vous devrez aller au-delà de mes connaissances et de regarder comment le coup de pouce de préprocesseur métaprogrammation bibliothèque n'ses inclure des macros. Vous pouvez effectivement trouver que cette bibliothèque se termine jusqu'à ce que vous voulez de plus facile.
En tout cas, ça ne va pas être aussi jolie que vous le souhaitez, ni, à mon humble avis, lisible et, tout comme la première alternative, il est présenté.
OriginalL'auteur Crazy Eddie
Probablement, chaque module doit se référer à la "Foo::Une" classe, et vous pouvez placer la définition de macro dans le début du module qui a besoin des autres version de "A".
Mais cela rend le code plus difficile à comprendre. Peut-être, si vous devez choisir entre les implémentations d'un objet, vous pouvez utiliser une fonction de fabrication. Que ferait votre intention explicite dans le code.
OriginalL'auteur Alsk
Méthode 2.
je travaille toujours avec ces règles simples:
1.) Le code Source doit être CLAIR, FACILE À COMPRENDRE et FACTICE-PREUVE.
-Un bon produit n'est pas construit par une seule personne. Simple, intuitif et facile-à-suivez le formatage va rendre la vie de tout le monde plus heureux.
2.) Si il n'y aura pas de différence de performances dans le produit final, s'en tenir à la règle n ° 1
-Il n'a pas de sens pour les développeurs de passer méninges sur quelque chose qui ne bénéficient pas de fin à la clientèle.
3.) Design élégant sera toujours fonctionne très bien, donc règle n ° 2 toujours vrai.
-La même règle s'applique à Dieu, prenez un miroir et regardez-vous 🙂
OriginalL'auteur YeenFei