使用宏创建锅炉板代码

时间:2011-05-07 22:21:07

标签: c++ macros c-preprocessor

我有一堆类,如下所示,


class SomeClass : public Function{
public:

   ref call(ref args){
    // do & return stuff
   }

   int getType(){return TYPE;}
   ref toString(){ return "SomeClass";}
};

我有50个这样的,唯一不同的是调用函数的主体。是否有可能有一个名称和正文的宏,并用名称和插入体替换“SomeClass”到调用函数?

3 个答案:

答案 0 :(得分:4)

不确定。如果您有一个支持可变参数宏的编译器,则扩展call成员函数的主体会更容易一些。虽然我使用了Boost.Preprocessor的stringize宏,但编写自己的宏很简单。

#define DEFINE_CLASS(name, parenthesized_call_body)                 \
    class name : public Function {                                  \
        ref call (ref args) {                                       \
            DEFINE_CLASS_CALL_BODY parenthesized_call_body          \
        }                                                           \
        int getType() { return TYPE; }                              \
        const char* toString() { return BOOST_PP_STRINGIZE(name); } \
    };

#define DEFINE_CLASS_CALL_BODY(...) __VA_ARGS__

用作:

DEFINE_CLASS(SomeClass, (return ref()))

call正文需要加上括号,以便正文中出现的任何逗号不会被视为宏参数分隔符。或者,您可以在类定义中声明call函数,然后单独定义该函数。

答案 1 :(得分:2)

为避免在宏调用中包装函数体,可以将类定义宏拆分为前缀和后缀:

#define DEFINE_FUNCTION_CLASS_BEGIN(name) \
    class name : public Function { \
    public: \
        ref call(ref args) {

#define DEFINE_FUNCTION_CLASS_END \
        } \
        int getType() { return TYPE; } \
        void toString() { return #name; } \
    };

调用:

DEFINE_FUNCTION_CLASS_BEGIN(SomeClass)

// Stuff.

DEFINE_FUNCTION_CLASS_END

或者,使用模板:

template<int Type>
class SomeClass : public Function {
public:
    int getType() { return Type; }
    ref call(ref args) {}
    std::string toString() {}
};

并专注于:

template<>
ref SomeClass<TYPE>::call(ref args) {
    // Stuff.
};

template<>
std::string SomeClass<FOO>::toString() {
    return "FOO";
};

答案 2 :(得分:0)

您使用了群发getType()toString()功能?这不是Java或C#,看着你的代码,我认为你需要一些额外的C ++学费 - 另一个例子是你从返回void 的函数返回“SomeClass”。

但是,你想要的是一个非常简单的模板。

template<typename T> class SomeClass : public Function {
    T t;
public:
    SomeClass(const T& ref)
        : t(ref) {}
    ret call(args) {
        return t(args);
    }
    int getType() { return TYPE; }
    std::string toString() { return "someClass"; } 
};

ret func(argtypes) { ... }
SomeClass<ret(*)(argtypes)> instance(func);
struct lols {
    // .. Whatever you want in here
    ret operator()(args) { ... };
}
SomeClass<lols> anotherinstance(lols()); // or constructor arguments if needed