C++ 每个令牌的可变宏扩展

C++ 每个令牌的可变宏扩展,c++,c,c-preprocessor,C++,C,C Preprocessor,假设我有一个宏,一个简单的宏,只为不同类型调用函数foo: #define FOO(type) foo_##type(); 一次,假设我想把它称为多种不同类型的东西。具体而言 foo_int(); foo_float(); foo_point2d(); 我想用一个名为FOO2的宏生成上述代码 #define FOO2(args...) --fill--here 为了完整起见,FOO2(int,float,point2d)应该扩展到上面的小代码段中。对于宏,这可能吗?如何在可变宏令牌包中为每

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

#define FOO(type) foo_##type();
一次,假设我想把它称为多种不同类型的东西。具体而言

foo_int();
foo_float();
foo_point2d();
我想用一个名为
FOO2
的宏生成上述代码

#define FOO2(args...) --fill--here
为了完整起见,
FOO2(int,float,point2d)
应该扩展到上面的小代码段中。对于宏,这可能吗?如何在可变宏令牌包中为每个参数执行不同的、单独的操作


我相信这样的问题已经被提出了。我搜索了另外两个结果,为每个宏实现显示了某种类型的
,非常复杂和通用。这就是为什么我决定询问我的特定用例并开始一个新问题。

是的,这是可能的,但需要多个宏

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

你想解决的真正问题是什么?不,不是关于用宏来做这类事情,而是你认为解决方案的真正问题是用宏来做这类事情,所以这就是你要问的。你可以说,我试图通过使用宏注释来自动生成结构的setter和getter,结果我需要这样的东西。这不是一个好主意,只是一个实验。但实际上,解决这个孤立的案例是我的任务。问题是,核心C++中的“自动生成”很少,而你正在与潮流抗争。在过去类似的情况下,我使用了XML定义和一些样式表来生成类声明,以及修改每个类成员的方法。最终的结果是枯燥乏味的,花园式的C++。为正确的工作使用正确的工具。查看宏的功能,如
BOOST\u FUSION\u ADAPT\u STRUCT
,我认为这也是可能实现的。这可能也会让你感兴趣:-宏支持空参数,因此你可以有一个带有多个参数的宏,如果你不关心一些额外的逗号,可以传递空参数。