范围内的枚举声明是宏的参数

发布于 2024-08-11 15:00:02 字数 936 浏览 2 评论 0原文

我正在尝试创建一个以范围作为参数的宏。
我知道,这可能不是一件好事等等
我正在尝试这个,但遇到了预处理器查找逗号和括号的问题......问题出在枚举上。

如何在作为宏参数的范围内声明枚举?

当编译器看到枚举项之间的逗号时,它会将其作为分隔符。

如果您想知道我为什么要这样做,是因为我需要注册我的命名空间和类,对于命名空间,我需要知道它们何时关闭,所以我想创建一个宏,该宏最初调用一个注册的静态函数命名空间,封装其内容,最后调用一个静态函数,从注册表中删除命名空间。
使用宏,编码员可以更轻松地执行此操作,并确保他不会忘记删除括号末尾的名称空间。

谢谢,

编辑:

我想要一个接受范围作为参数的宏:

#define MYMACRO(unkownscope) unknownscope

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

现在,如果我尝试:

#define MYMACRO(unkownscope) unknownscope

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

由于枚举内的逗号,它不会编译,因为编译器认为它是宏的分隔符。括号内的逗号不会发生这种情况,例如:

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

会正常编译,因为逗号位于双括号内。

抱歉,无法提前解释...我的英语不太好,这些单词一直跳过我=[

Ty 寻求答案!

I am trying to create a macro that takes a scope as a parameter.
I know, it is probably not a good thing etc etc.
I was trying this and got the problem that preprocessor looks for commas and parentheses... the problem is with enum.

How would I declare a enum inside a scope that is a parameter of a macro?

when the compiler see the comma between enum itens, it takes it as a separator.

If you are curious to know why I entered into this, is because I need to register my namespaces and classes, for namespaces I need to know when they are closed, so I was thinking to create a macro that initially calls a static function that register the namespace, encapsulate its contents and finally call a static function that removes the namespace from the registry.
With a macro it would be easier for the coder to do this and make sure he doesn't forget to remove the namespace in the end of the bracket.

Thanks,
Joe

EDIT:

I want a macro that accepts a scope as parameters:

#define MYMACRO(unkownscope) unknownscope

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

now, if I try:

#define MYMACRO(unkownscope) unknownscope

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

it won't compile because of the comma inside the enum, because the compiler thinks it is a separator of the macro. It doesn't happen with commas inside parentheses, example:

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

would compile normally because the comma is inside a double parentheses.

Sorry for not being able to explain earlier... my english is not that good and the words just keep skipping me =[

Ty for the answers!
Joe

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浅浅淡淡 2024-08-18 15:00:02

听起来您正在将预处理器推到超出其愿意的范围。虽然它不是那么优雅,但如何将宏分成两部分(一个前置宏和一个后置宏),而不是传递“范围”作为参数,而是用前置宏和后置宏包围您的范围。

所以,如果你的宏看起来像这样:

SOMACRO({ ... });

你会这样做:

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

It sounds like you are pushing the preprocessor beyond where it's willing to go. While it's not as elegant, how about breaking your macro in two (one pre- and one post-) and rather then passing a "scope" as parameter, you surround your scope with you pre- and post- macros.

So, if your macro looks something like:

SOMACRO({ ... });

You would instead do something like:

PRESOMACRO();
{ ... };
POSTSOMACRO();
滴情不沾 2024-08-18 15:00:02
#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
#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
怀里藏娇 2024-08-18 15:00:02

您正在尝试使用宏复制 RAII。

#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
} 

我不知道你在谈论枚举什么。

You are attempting to replicate RAII with a 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
} 

I have no idea what you are talking about with regard to enums.

卖梦商人 2024-08-18 15:00:02

您已经注意到问题所在, 上的一篇 文章 boostpro.com 总结了问题。
有解决方法,但我会选择使用 Boost.Preprocessor

在不确切知道您想要在语法上实现什么的情况下,您可能正在寻找类似的东西(编辑为 PP_SEQ):

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

You already noticed what the problem is, an article on boostpro.com sums the problem up.
There are work-arounds, but i'd go for utilizing Boost.Preprocessor.

Without knowing exactly what you're trying to achieve syntactically, something like this might be what you are looking for (edited to PP_SEQ):

#define MAKE_ENUM(Name, Seq) enum Name { BOOST_PP_SEQ_ENUM(Seq) }
MAKE_ENUM(foo, (a)(b)(c));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文