每个标记的可变宏扩展

Variadic macro expansion for each token

假设我有一个宏,一个简单的宏,它只是为不同类型调用一个函数 foo

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

假设我想为多种不同的类型调用这个东西。具体;

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

我想用一个名为 FOO2 的宏生成上面的代码。

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

为了完整起见,FOO2(int, float, point2d) 应该扩展为上面的小代码片段。这对宏来说可能吗?如何为可变宏标记包中的每个参数做不同的、单独的事情?

我确定已经有人问过这样的问题。我搜索了其他几个结果,显示了某种相当复杂和通用的 FOR_EACH 宏实现。这就是为什么我决定询问我的具体用例并开始一个新问题。

可以,但需要多个宏。

#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);

以上将生成:

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

如果您不想将数字指定为参数,请添加以下内容:

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

现在你只需要做:

FOO3(int, float, double);

通过更多的工作,您甚至可以使宏与任何函数名称一起工作:

#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);

结果:

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