问题
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