我可以附加到预处理器宏吗?
在标准C或GNU扩展中有什么方法可以将内容附加到宏定义中吗?例如,给定宏定义为
#define List foo bar
我可以追加bas
使它List
扩展,就像我定义它一样
#define List foo bar bas
?
我希望我能做到这样的事情:
#define List foo bar bas
#define List_ Expand(List)
#undef List
#define List Expand(List_) quux
但我无法弄清楚如何定义Expand()
宏,所以它会做我想要的。
动机:
我正沿着以下方式玩歧视/标记的联盟:
struct quux_foo { int x; };
struct quux_bar { char *s; };
struct quux_bas { void *p; };
enum quux_type {quux_foo, quux_bar, quux_bas};
struct quux {
enum quux_type type;
union {
struct quux_foo foo;
struct quux_bar bar;
struct quux_bas bas;
} t;
};
我认为这是X-macro的好地方。如果我定义一个宏
#define quux_table X(foo) X(bar) X(bas)
枚举&结构可以这样定义,永远不会失去同步:
#define X(t) quux_ ## t,
enum quux_type {quux_table};
#undef X
#define X(t) struct quux_ ## t t;
struct quux {
enum quux_type type;
union {quux_table} t;
};
#undef X
当然,quux_*
结构可能会失去同步,所以我想做一些这样的事情,只有合法的:
struct quux_foo { int x; };
#define quux_table quux_table X(foo)
struct quux_bar { char *s; };
#define quux_table quux_table X(bar)
struct quux_bas { void *p; };
#define quux_table quux_table X(bas)
(嗯,我真正希望能做的就是这样
member_struct(quux, foo) { int x; };
但我很清楚宏不能从宏中重新定义。)
无论如何,那是我激励的榜样。有没有办法实现这个目标?
Boost.Preprocessor示例很好,如果您可以告诉我如何使X-macro技术与该库一起工作。
没有找到相关结果
已邀请:
3 个回复
痴浪墨
时,它的替换列表是四个令牌
,
,
和
的序列。没有任何方法可以将宏扩展为替换列表。 所有宏替换都在调用宏时发生。 我建议使用Boost.Preprocessor库来自动生成代码。这有点工作,但你可以使用它完成一些相当令人印象深刻的事情。它应该与C完全兼容。
凸晴
这个选项应该使自动代码生成更容易,但不幸的是只在gcc上(可能是clang,还没有测试过) 说实话,没有理由我可以找到为什么这必须起作用,这很可能是未定义的行为恰好起作用。我猜测的原因是,在弹出foo之后,当前正在扩展的宏不再与名称foo相关联,这允许扩展符号
,但这只是我猜想的 编辑: 在对clang进行测试之后,这对clang不起作用。 我不知道为什么我认为clang不起作用,也许它不是在不同的机器上。我确实让它使用了给出的代码
距相镭