我可以附加到预处理器宏吗? [英] Can I append to a preprocessor macro?
问题描述
在标准 C 或 GNU 扩展中是否有任何方法可以将内容附加到宏定义中?例如,给定一个定义为
的宏#define List foo bar
我可以附加 bas
以便它 List
像我定义它一样扩展#define List foo bar bas
?
Is there any way in standard C—or with GNU extensions—to append stuff to a macro definition? E.g., given a macro defined as
#define List foo bar
can I append bas
so that it List
expands as if I’d defined it
#define List foo bar bas
?
我希望我能做这样的事情:
I was hoping I could do something like this:
#define List foo bar bas
#define List_ Expand(List)
#undef List
#define List Expand(List_) quux
但我不知道如何定义 Expand()
宏,所以它会做我想做的事.
but I can’t figure out how to define the Expand()
macro so it’ll do what I want.
动机:我正在按照这些思路与受歧视/标记的工会一起玩:
Motivation: I’m playing with discriminated/tagged unions along these lines:
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)
枚举和结构可以这样定义,并且永远不会不同步:
I figure this is a good place for the X-macro. If I define a macro
#define quux_table X(foo) X(bar) X(bas)
the enumeration & structure can be defined thus, and never get out of sync:
#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_*
结构可能会不同步,所以我想做这样的事情,只是合法的:
Of course, the quux_*
structures can get out of sync, so I’d like to do something like this, only legally:
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;};
但我很清楚不能从宏中(重新)定义宏.)
(Well, what I really want to be able to do is something like
member_struct(quux, foo) { int x; };
but I’m well aware that macros cannot be (re)defined from within macros.)
无论如何,这是我的激励例子.有没有办法做到这一点?
Anyhow, that’s my motivating example. Is there a way to accomplish this?
Boost.Preprocessor 示例很好,如果您能告诉我如何使 X-macro 技术与该库一起工作.
Boost.Preprocessor examples are fine, if you can show me how to make the X-macro technique work with that library.
推荐答案
实际上,没有.
宏是惰性求值的.当你#define List_Expand(List)
时,它的替换列表是Expand
、(
、List这四个记号的序列代码> 和 <代码>)代码>.没有任何方法可以将宏扩展为替换列表.
Macros are lazily evaluated. When you #define List_ Expand(List)
, its replacement list is the sequence of four tokens Expand
, (
, List
, and )
. There isn't any way to expand a macro into a replacement list.
所有宏替换都发生在调用宏时.
All macro replacement takes place when a macro is invoked.
我建议使用 Boost.Preprocessor 库进行自动代码生成.这有点工作,但你可以完成一些 相当令人印象深刻的东西使用它.它应该与 C 完全兼容.
I'd recommend looking at using the Boost.Preprocessor library for automatic code generation. It's a bit of work, but you can accomplish some fairly impressive things using it. It should be fully compatible with C.
这篇关于我可以附加到预处理器宏吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!