Variadic macro expansion for each token

。_饼干妹妹 提交于 2020-03-03 06:30:36

问题


Suppose I have a macro, a simple one that just calls a function foo for different type:

#define FOO(type) foo_##type();

In one go, let's say I want to call this thing for multiple different types. Concretely;

foo_int();
foo_float();
foo_point2d();

I want to generate above code with a macro called FOO2.

#define FOO2(args...) --fill--here

And just to be complete, FOO2(int, float, point2d) should expand into the above small code snippet. Is this possible with macros and how to do a different, separate thing for each argument in a variadic macro token pack?

I am sure a question like this is already asked. I searched for couple of other results, showing some sort of FOR_EACH macro implementation that were quite complicated and general. That's why I decided to ask for my specific use-case and started a new question.


回答1:


Yes, it's possible, but requires multiple macros.

#define MAP1(m,t,...) m(t)
#define MAP2(m,t,...) m(t); MAP1(m,__VA_ARGS__)
#define MAP3(m,t,...) m(t); MAP2(m,__VA_ARGS__)
// ... add more as needed ...
#define MAP(n,...) MAP##n(__VA_ARGS__)

#define FOO(type) foo_##type()
#define FOON(n, ...) MAP(n, FOO, __VA_ARGS__)

FOON(3, int, float, double);

The above will generate:

foo_int(); foo_float(); foo_double();

If you don't want to specify the number as argument, add the following:

#define FOO1(...) FOON(1, __VA_ARGS__)
#define FOO2(...) FOON(2, __VA_ARGS__)
#define FOO3(...) FOON(3, __VA_ARGS__)
// ... add more as needed ...

And now you can just do:

FOO3(int, float, double);

With a bit more work you can even make the macro work with any function name:

#define MAP1(m,f,t,...) m(f,t)
#define MAP2(m,f,t,...) m(f,t); MAP1(m,f,__VA_ARGS__)
#define MAP3(m,f,t,...) m(f,t); MAP2(m,f,__VA_ARGS__)
// ...
#define MAP(n,...) MAP##n(__VA_ARGS__)

#define CALL(funcname, type) funcname##_##type()
#define CALLN(n, funcname, ...) MAP(n, CALL, funcname, __VA_ARGS__)

#define CALL1(...) CALLN(1, __VA_ARGS__)
#define CALL2(...) CALLN(2, __VA_ARGS__)
#define CALL3(...) CALLN(3, __VA_ARGS__)
// ...

CALL1(foo, int);
CALL2(bar, float, double);
CALL3(baz, whatever, you, want);

Result:

foo_int();
bar_float(); bar_double();
baz_whatever(); baz_you(); baz_want();


来源:https://stackoverflow.com/questions/60105647/variadic-macro-expansion-for-each-token

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