0

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);\
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
André Puel
  • 8,741
  • 9
  • 52
  • 83
  • I guess there is some duplicate somewhere in Stackoverflow, but I did not find anything related to this problem because I do not know how to phrase correctly the question. – André Puel Jul 08 '14 at 20:48
  • 3
    Have you heard of variadic templates? – 101010 Jul 08 '14 at 20:49
  • @40two, Yes. In fact, `other_func` and `one_func` are defined this way in my context. – André Puel Jul 08 '14 at 20:54
  • 1
    @AndréPuel why not write a proper forwarding variadic template function then? Do you really need the macro? – Pradhan Jul 08 '14 at 21:03
  • Even with a proper forwarding variadic template I would still need to define the function with a macro. I edited the question to show my point. – André Puel Jul 08 '14 at 21:38
  • 1
    To me, this seems just plain wrong... To get a good answer, you probably should describe the actual problem you are seeing, rather than asking about your preferred solution. Aka "you are asking an XY Question". – Mats Petersson Jul 08 '14 at 22:07
  • 1
    @MatsPetersson http://stackoverflow.com/questions/24643183/how-to-do-a-runtime-subclassing-system There you go – André Puel Jul 08 '14 at 23:35

1 Answers1

0

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.

unDeadHerbs
  • 1,306
  • 1
  • 11
  • 19