2010-03-02 87 views
3

我正在寻找一种方法或一种方法来从列表中生成typedefs列表和对象实例化列表宏调用,定义这些对象的类类型和构造函数参数。C/C++宏:如何使用一个宏(boost预处理器库?)生成两个单独的代码段

它应该看起来像下面的(不工作)代码。要解决的问题是从一个宏调用列表中生成两个不同列表的方法。我想这是一个问题,需要使用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); 
} 

回答

2

宏技巧...

如果你想在C宏展开循环,你需要有尽可能多的macroes的迭代(与预处理,你还可以玩其他的技巧与包括递归的文件,但是你没有像界面这样的宏)。

我已经添加和结束标记,我不知道它是否真的需要。

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

因此,这里有些东西正在做你想做的事情 - 修改后的界面和最多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, , ,) 
) 
+0

感谢您的快速解决方案 - 它的工作原理! 生成TYPE0_DEF,TYPE1_DEF等.pp.宏接缝将成为boost-preprocessor-library的候选者。我会尽快尝试。 再次感谢! – Marcel 2010-03-02 13:19:58