【问题标题】:Enum declaration inside a scope that is a parameter of a macro范围内的枚举声明是宏的参数
【发布时间】:2010-12-18 12:17:14
【问题描述】:

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

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

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

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

谢谢,

编辑:

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

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

可以正常编译,因为逗号在双括号内。

抱歉没能早点解释……我的英文不是很好,单词一直跳过我=[

回答问题!

【问题讨论】:

  • 您能定义一下您的作用域吗?举几个例子?
  • 如何注册命名空间?
  • 我能想到的唯一一种带有括号的枚举声明形式是for:for(enum foo { a, b, c };;) ;。你可以让它总是传递(enum-declaration;finish;),其中finish 是由宏构造的一些布尔循环控制变量。
  • 对不起,我不得不去,直到现在才看答案。我将编辑帖子以帮助您,但我猜 Klatchko 回答了它。
  • 请注意GCC(可能还有其他人,因为它是 C99 和 C++0x)有可变参数宏,所以你可以这样做 #define MYMACRO(...) __VA_ARGS__

标签: c++ scope macros enums brackets


【解决方案1】:

听起来你正在将预处理器推到它愿意去的地方。虽然它不那么优雅,但如何将宏分成两部分(一个 pre- 和一个 post-),而不是将“范围”作为参数传递,而是用 pre-和 post- 宏包围你的范围。

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

SOMACRO({ ... });

你会改为:

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

【讨论】:

  • 是的,我在帖子中说过。我只是在验证是否有其他方法,用于学习目的。使用两个宏之间的区别,一个在作用域的开头,一个在结尾,编码人员可以忘记其中一个,特别是结尾的那个。我要做的是创建调用初学者和完成者宏的完整宏,如果编码器需要枚举,那么他不会使用这个宏而是完整的方式,或者我应该推动它只使用两个宏,不管忘记结局的缺陷?
【解决方案2】:
#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

【讨论】:

    【解决方案3】:

    您正在尝试使用宏复制 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
    } 
    

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

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-07
        • 2017-08-30
        • 2020-06-08
        相关资源
        最近更新 更多