2009-11-19 16 views
0

J'essaie de créer une macro qui prend une portée en tant que paramètre.
Je sais, ce n'est probablement pas une bonne chose, etc.
J'essayais cela et j'ai eu le problème que le préprocesseur recherche des virgules et des parenthèses ... le problème est avec enum.Enum déclaration à l'intérieur d'une portée qui est un paramètre d'une macro

Comment déclarer une énumération dans une étendue qui est un paramètre d'une macro? Lorsque le compilateur voit la virgule entre enum itens, il le prend comme séparateur.

Si vous êtes curieux de savoir pourquoi je suis entré dans ce domaine, c'est parce que j'ai besoin d'enregistrer mes espaces de noms et classes, pour les espaces de noms que je dois savoir quand ils sont fermés, donc je pensais créer une macro qui appelle fonction statique qui enregistre l'espace de noms, encapsule son contenu et appelle enfin une fonction statique qui supprime l'espace de noms du registre.
Avec une macro, il serait plus facile pour le codeur de faire cela et de s'assurer qu'il n'oublie pas de supprimer l'espace de noms à la fin du support.

Merci,
Joe

EDIT:

Je veux une macro qui accepte un champ en tant que paramètres:

#define MYMACRO(unkownscope) unknownscope 

class MYMACRO({ 
    // please, don't take this code seriously, it is just an example so you can understand my question 
}); 

maintenant, si je tente:

#define MYMACRO(unkownscope) unknownscope 

class MYMACRO({ 
    enum { 
    anything = 1, 
    everything = 2 
    }; 
}); 

il ne compilera pas en raison de la virgule à l'intérieur de l'enum, parce que le co mpiler pense que c'est un séparateur de la macro. Il ne se fait pas par des virgules dans les parenthèses, par exemple:

int a(){ 
    int x = anyfunction(1, 2); 
} 

compilerions normalement parce que la virgule est un double entre parenthèses.

Désolé pour ne pas être en mesure d'expliquer plus tôt ... mon anglais est pas bon et les mots me garder sauter = [

Ty pour les réponses!
Joe

+2

Pourriez-vous définir ce que vous entendez comme un champ d'application? Donner quelques exemples? –

+2

S'il vous plaît poster vos tentatives ... –

+0

Comment enregistrer un espace de noms? – jmucchiello

Répondre

1

Il semble que vous poussiez le préprocesseur au-delà de ce qu'il est prêt à faire. Bien que ce ne soit pas aussi élégant, que diriez-vous de casser votre macro en deux (une pré- et une post-) et plutôt de passer une "portée" en paramètre, vous entourez votre portée de pré et post-macros.

Donc, si votre macro ressemble à:

SOMACRO({ ... }); 

Vous plutôt faire quelque chose comme:

PRESOMACRO(); 
{ ... }; 
POSTSOMACRO(); 
+0

oui, je l'ai dit sur mon post . Je vérifiais simplement s'il y avait un autre moyen, à des fins d'apprentissage. La différence entre l'utilisation de deux macros, une au début et une à la fin, est que le codeur peut oublier l'une d'entre elles, en particulier celle qui se termine. Ce que je vais faire est de créer la macro complète qui appelle les macros débutant et finisseur et si le codeur a besoin d'enums, alors il n'utilisera pas cette macro mais de manière complète, ou devrais-je la pousser pour n'utiliser que les deux macros, défaut d'oublier la fin? – Jonathan

0
#define SCOPED_STUFF(pre,post) pre; STUFF; post; 

#define STUFF enum {a,b,c} 
SCOPED_STUFF(a,b) 
#undef STUFF 

#define STUFF enum {q,r} 
SCOPED_STUFF(c,d) 
#undef STUFF 
0

Vous essayez de reproduire RAII avec une macro.

#define SCOPE(ns) NamespaceRegistrar _ns_rar(ns); 
struct NamespaceRegistrar { 
    std::string _ns; 
    NamespaceRegistrar(const std::string& ns) : _ns(ns) { AcquireResource(_ns); } 
    ~NamespaceRegistrar() { ReleaseResource(_ns); } 
}; 


{ 
    SCOPE("Foo") 
    // stuff 
} 

Je n'ai aucune idée de ce dont vous parlez en ce qui concerne les énumérations.

0

Vous avez déjà remarqué ce que le problème est, une article sur boostpro.com sommes le problème vers le haut. Il ya des solutions de rechange, mais je voudrais utiliser Boost.Preprocessor.

Sans savoir exactement ce que vous essayez d'atteindre syntaxiquement, quelque chose comme cela pourrait être ce que vous cherchez (sous la direction de PP_SEQ):

#define MAKE_ENUM(Name, Seq) enum Name { BOOST_PP_SEQ_ENUM(Seq) } 
MAKE_ENUM(foo, (a)(b)(c));