Is there an easier way to do a macro to define a function with variable amount of arguments?

北慕城南 提交于 2019-12-11 18:47:34

问题


I have a macro that defines a function with a variable amount of arguments, the macro has some logic to decide which real function must be called. My current approach is the following:

#define FUNC(ret,args,args_call) \
    ret my_func(args) { \
        if( something ) other_func(args_call);\
        return one_func(args_call);\
    }
#define PARAM(...) __VA_ARGS__

I use it like that:

class AClass : public AInterface {
public:
    FUNC(int,PARAM(int a, int b),PARAM(a,b))
};

I was wondering if there is a better way to do that.

Note: The declared (my_func in my example) function will be used to reimplement a method from the super class, so the approaches using templates (the ones that I am aware of) will not solve my problem.

Edit2: Even using a proper variadic templated function, I still need the macro to declare the function because it overrides a function in the superclass.

#define FUNC(ret,args,args_call) \
ret my_func(args) { \
    return proper_variadic_templated_function<ret>(args_call);\
}

回答1:


If we use the EVAL, helper, and Conditional macros from the first two code blocks here. We can create some recursive macros to parse the parameter array.

As the comma is syntactic we will need to escape it for outputting.

#define COMMA() ,

We can generate two functions to separate the types from the names.

#define I_WT_R() I_WT
#define I_WT(t,v,n,...) \
    t v IS_DONE(n)(      \
        EAT               \
    ,                      \
       OBSTRUCT(COMMA)()    \
       OBSTRUCT(I_WT_R)()    \
    )(n,__VA_ARGS__)
#define WithTypes(...) I_WT(__VA_ARGS__,DONE)

And.

#define I_WoT_R() I_WoT
#define I_WoT(t,v,n,...) \
    v IS_DONE(n)(         \
        EAT                \
    ,                       \
        OBSTRUCT(COMMA)()    \
        OBSTRUCT(I_WoT_R)()   \
    )(n,__VA_ARGS__)
#define WithoutTypes(...) I_WoT(__VA_ARGS__,DONE)

Redefining your macro as such:

#define FUNC(ret,args) EVAL(                           \
    ret my_func(WithTypes args) {                      \
        if( something ) other_func(WithoutTypes args); \
        return one_func(WithoutTypes args);            \
    })

Allows you the slightly better syntax of:

class AClass : public AInterface {
public:
    FUNC(int,(int,a,int,b))
};

Compiling to (after adding newlines):

class AClass : public AInterface {
public:
    int my_func(int a , int b ) {
        if( something )
            other_func(a , b );
        return one_func(a , b );
    }
};

Hope that helps.



来源:https://stackoverflow.com/questions/24641375/is-there-an-easier-way-to-do-a-macro-to-define-a-function-with-variable-amount-o

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!