c++ - 每个标记的可变宏扩展

标签 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) 应该扩展为上面的小代码片段。这对于宏来说是可能的吗?如何为可变参数宏 token 包中的每个参数执行不同的、单独的操作?

我确信已经有人问过这样的问题了。我搜索了其他几个结果,显示了某种非常复杂和通用的 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();

关于c++ - 每个标记的可变宏扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60105647/

相关文章:

objective-c - 从包含宏名称的 NSString 获取宏值

C++ 是否可以使用宏从调用它的地方打印类函数?

c++ - 使用 Doxygen 记录预处理器选项

c++ - 成员函数的 moveToThread

c++ - std::sort 中用 lambda 函数指定的比较函数是否返回 bool 类型?

c++ - 如何在CPP中获取MS Office的部分产品 key

c++ - 以安全的方式替换 memcpy

c - ATmega8 加/减计数器计数不正确

c - 在 C 中使用 free 命令时出错

c - 如何更改 termios 配置,以便在用户按下 <tab> 键时 getc() 立即返回?