【问题标题】:C/C++ Macro: How to generate two separate sections of code with one macro (boost preprocessor library?)C/C++ 宏:如何使用一个宏生成两个单独的代码段(增强预处理器库?)
【发布时间】:2011-01-22 15:08:19
【问题描述】:

我正在寻找一种方法或方式来从宏调用列表中生成 typedef 列表和对象实例化列表,定义这些对象的类类型和构造函数参数。

它应该看起来像下面的(不工作的)代码。要解决的问题是一种从一个宏调用列表中生成两个不同列表的方法。我想这是一个需要通过 boost 预处理器库部分解决的问题,但我现在已经掌握了如何做。

/////////////////////////////////////////////////////////////////////////////////
// MACRO-Definitions
#define DEF_OBJECT_TYPE(name, class, contructor_params) \
  typedef class name ## type;
  name ## type* name;

#define DEF_OBJECT_RUN(name, class, contructor_params) \
  name ## type* name = new name ## type contructor_params; \

#define DEF_OBJECTS(definitions) \
  /* Type-Header */ \
  definitions \
  /* Type-Footer */ \
  /* Run-Header */ \
  definitions \
  /* Run-Footer */

#define OBJECT(name) (dynamic_cast<name ## type*>(name))

/////////////////////////////////////////////////////////////////////////////////
// Object-Definitions
DEF_OBJECTS(
  DEF_OBJECT(Object1, CClass1, ("par1"))
  DEF_OBJECT(Object2, CClass2, ("par1", "par1"))
)

/////////////////////////////////////////////////////////////////////////////////
// This shall be the result of the macro expansion
// shall expand to:
struct MyClass {

  typedef class Object1type;
  Object1type* Object1;

  typedef class Object2type;
  Object2type* Object2;

  void Run();
}

void MyClass::Init() {
  Object1type* Object1 = new Object1type("par1");
  Object2type* Object2 = new Object2type("par1", "par2");
}
// end of expansion
/////////////////////////////////////////////////////////////////////////////////

// I want to use these automatic created objects in this way:
void MyClass::Run() {
  OBJECT(Object1)->method_class1(1);
  OBJECT(Object2)->method_class2(1,2);
}

【问题讨论】:

    标签: c++ boost macros boost-preprocessor


    【解决方案1】:

    宏观技巧...

    如果你想在 C 宏中展开循环,你需要有与迭代一样多的宏(使用预处理器,你也可以通过递归包含文件来玩其他技巧,但是你没有像这样的宏界面)。

    我已经加了end marker,不知道是不是真的需要。

    我确实通过构建宏名称来分派到一个空的结尾宏或一个连续的宏。

    所以这里有一些做你想做的事情——带有修改过的界面和最多 4 个对象。只需为更多对象添加类似的宏即可。

    #define TYPE_DEF_OBJECT(name, class, constructor_params) \
      typedef class name ## type; \
      name ## type* name;
    
    #define TYPE_DEF_END(name, class, constructor_params)
    
    #define TYPE4_OBJECT(name, class, constructor_params) \
        TYPE_DEF_OBJECT(name, class, constructor_params) TYPE5
    #define TYPE4_END(name, class, constructor_params) \
        TYPE_DEF_END(name, class, constructor_params)
    #define TYPE4(kind, name, class, constr) \
        TYPE4_##kind(name, class, constr)
    
    #define TYPE3_OBJECT(name, class, constructor_params) \
        TYPE_DEF_OBJECT(name, class, constructor_params) TYPE4
    #define TYPE3_END(name, class, constructor_params) \
        TYPE_DEF_END(name, class, constructor_params)
    #define TYPE3(kind, name, class, constr) \
        TYPE3_##kind(name, class, constr)
    
    #define TYPE2_OBJECT(name, class, constructor_params) \
        TYPE_DEF_OBJECT(name, class, constructor_params) TYPE3
    #define TYPE2_END(name, class, constructor_params) \
        TYPE_DEF_END(name, class, constructor_params)
    #define TYPE2(kind, name, class, constr) \
        TYPE2_##kind(name, class, constr)
    
    #define TYPE1_OBJECT(name, class, constructor_params) \
        TYPE_DEF_OBJECT(name, class, constructor_params) TYPE2
    #define TYPE1_END(name, class, constructor_params) \
        TYPE_DEF_END(name, class, constructor_params)
    #define TYPE1(kind, name, class, constr) \
        TYPE1_##kind(name, class, constr)
    
    #define TYPE0_OBJECT(name, class, constructor_params) \
        TYPE_DEF_OBJECT(name, class, constructor_params) TYPE1
    #define TYPE0_END(name, class, constructor_params) \
        TYPE_DEF_END(name, class, constructor_params)
    #define TYPE(kind, name, class, constr) \
        TYPE0_##kind(name, class, constr)
    
    
    #define RUN_DEF_OBJECT(name, class, constructor_params) \
      name ## type* name = new name##type constructor_params; 
    
    #define RUN_DEF_END(name, class, constructor_params)
    
    #define RUN4_OBJECT(name, class, constructor_params) \
        RUN_DEF_OBJECT(name, class, constructor_params) RUN5
    #define RUN4_END(name, class, constructor_params) \
        RUN_DEF_END(name, class, constructor_params)
    #define RUN4(kind, name, class, constr) \
        RUN4_##kind(name, class, constr)
    
    #define RUN3_OBJECT(name, class, constructor_params) \
        RUN_DEF_OBJECT(name, class, constructor_params) RUN4
    #define RUN3_END(name, class, constructor_params) \
        RUN_DEF_END(name, class, constructor_params)
    #define RUN3(kind, name, class, constr) \
        RUN3_##kind(name, class, constr)
    
    #define RUN2_OBJECT(name, class, constructor_params) \
        RUN_DEF_OBJECT(name, class, constructor_params) RUN3
    #define RUN2_END(name, class, constructor_params) \
        RUN_DEF_END(name, class, constructor_params)
    #define RUN2(kind, name, class, constr) \
        RUN2_##kind(name, class, constr)
    
    #define RUN1_OBJECT(name, class, constructor_params) \
        RUN_DEF_OBJECT(name, class, constructor_params) RUN2
    #define RUN1_END(name, class, constructor_params) \
        RUN_DEF_END(name, class, constructor_params)
    #define RUN1(kind, name, class, constr) \
        RUN1_##kind(name, class, constr)
    
    #define RUN0_OBJECT(name, class, constructor_params) \
        RUN_DEF_OBJECT(name, class, constructor_params) RUN1
    #define RUN0_END(name, class, constructor_params) \
        RUN_DEF_END(name, class, constructor_params)
    #define RUN(kind, name, class, constr) \
        RUN0_##kind(name, class, constr)
    
    #define DEF_OBJECTS(definitions) \
      TYPE definitions \
      RUN definitions \
    
    DEF_OBJECTS(
      (OBJECT, Object1, CClass1, ("par1"))
      (END, , , )
    )
    

    【讨论】:

    • 感谢您的快速解决方案 - 它有效! TYPE0_DEF、TYPE1_DEF 等的生成.pp。宏接缝成为 boost-preprocessor-library 的候选者。我会尽快试试这个。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 2018-01-03
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 2015-05-08
    • 2020-02-09
    相关资源
    最近更新 更多