Search code examples
cmacrosc-preprocessor

Overloading Macro on Number of Arguments


I have two macros FOO2 and FOO3:

#define FOO2(x,y) ...
#define FOO3(x,y,z) ...

I want to define a new macro FOO as follows:

#define FOO(x,y) FOO2(x,y)
#define FOO(x,y,z) FOO3(x,y,z)

But this doesn't work because macros do not overload on number of arguments.

Without modifying FOO2 and FOO3, is there some way to define a macro FOO (using __VA_ARGS__ or otherwise) to get the same effect of dispatching FOO(x,y) to FOO2, and FOO(x,y,z) to FOO3?


Solution

  • Simple as:

    #define GET_MACRO(_1,_2,_3,NAME,...) NAME
    #define FOO(...) GET_MACRO(__VA_ARGS__, FOO3, FOO2)(__VA_ARGS__)
    

    So if you have these macros, they expand as described:

    FOO(World, !)         // expands to FOO2(World, !)
    FOO(foo,bar,baz)      // expands to FOO3(foo,bar,baz)
    

    If you want a fourth one:

    #define GET_MACRO(_1,_2,_3,_4,NAME,...) NAME
    #define FOO(...) GET_MACRO(__VA_ARGS__, FOO4, FOO3, FOO2)(__VA_ARGS__)
    
    FOO(a,b,c,d)          // expands to FOO4(a,b,c,d)
    

    Naturally, if you define FOO2, FOO3 and FOO4, the output will be replaced by those of the defined macros.