Is there an easier way to make a macro to define a function with a variable number of arguments?

I have a macro that defines a function with a variable number of arguments, the macro has some logic to decide which real function to call. My current approach is this:

#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 this:

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 this.

Note. The my_func

function declared ( in my example) will be used to override the method from the superclass, so approaches using templates (the ones I know of) don't solve my problem.

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

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

      

0


source to share


1 answer


If we use macros EVAL

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

Since the comma is syntactic, we will need to escape it in order to output.

#define COMMA() ,

      

We can generate two functions to separate types from 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)

      



Revisiting 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 a slightly better syntax:

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

      

Compilation (after adding new lines):

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

      

Hope it helps.

0


source







All Articles