每个标记的可变宏扩展
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();
假设我有一个宏,一个简单的宏,它只是为不同类型调用一个函数 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();