Overloading a macro

家住魔仙堡 提交于 2020-01-01 17:07:30

问题


I'm trying to overload a macro by the number of parameter.
Of course I can't actually overload the macro.

I've tried using variadic macros to choose the right macro (using the fact that if __VA_ARGS__ doesn't exist it's supposed to delete the last coma before it - GCC Reference):

#define TEST1() printf("TEST1");
#define TEST2() printf("TEST2");

#define CHOOSER(x, y,FUNC,...) FUNC()

#define MANIMACRO(...) CHOOSER(,__VA_ARGS__,TEST1,TEST2)

int main(void)
{
    MANIMACRO(1);
    MANIMACRO();
}

The idea was that if __VA_ARGS__ exists it should pass 4 arguments to CHOOSER, where the third one should have been "disappeared" with the unused args. so TEST1 would be chosen.

If there is no parameter the __VA_ARGS__ would be null, and should have removed the coma, so TEST2 would be chosen and used.

So, i guess that doesn't work because the __VA_ARGS__ probably gets removed only at the end of the preprocessing stage, after the whole thing was already expanded.

So, how can I do such a thing? (in vs2010)


回答1:


Based on this answer:

#define TEST1(expr)           printf("test1")
#define TEST2(expr, explain)  printf("test2")

#define N_ARGS_IMPL2(_1, _2, count, ...) \
   count
#define N_ARGS_IMPL(args) \
   N_ARGS_IMPL2 args
#define N_ARGS(...) N_ARGS_IMPL((__VA_ARGS__, 2, 1, 0))
 /* Pick the right helper macro to invoke. */
#define CHOOSER2(count) TEST##count
#define CHOOSER1(count) CHOOSER2(count)
#define CHOOSER(count)  CHOOSER1(count)
 /* The actual macro. */
#define TEST_GLUE(x, y) x y
#define TEST(...) \
   TEST_GLUE(CHOOSER(N_ARGS(__VA_ARGS__)), \
               (__VA_ARGS__))

int main() {
  TEST(one); // singleArgumentExpansion(one)
  TEST(two, "foopy"); // twoArgumentExpansion(two, "foopy")
  return 0;
}



回答2:


First, the page you link explains it is a GCC extension. If you are using visual studio 2010 as your tag implies, I'm not surprised it doesn't work.

Then you aren't using it correctly: you need ## between the coma and __VA_ARGS__. If I do this and fix the typo which makes both TESTx macros print TEST1, I get the behaviour you expect with gcc 4.4

#include <stdio.h>

#define TEST1() printf("TEST1\n");
#define TEST2() printf("TEST2\n");

#define CHOOSER(x, y, FUNC,...) FUNC()

#define MANIMACRO(...) CHOOSER(,##__VA_ARGS__,TEST1,TEST2)

int main(void)
{
    MANIMACRO(1);
    MANIMACRO();
}


来源:https://stackoverflow.com/questions/11974170/overloading-a-macro

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