X-宏
一种在编译时生成重复代码结构的惯用技术。
X-macro 由两部分组成:列表和列表的执行。
例:
#define LIST \
X(dog) \
X(cat) \
X(racoon)
// class Animal {
// public:
// void say();
// };
#define X(name) Animal name;
LIST
#undef X
int main() {
#define X(name) name.say();
LIST
#undef X
return 0;
}
由预处理器扩展为以下内容:
Animal dog;
Animal cat;
Animal racoon;
int main() {
dog.say();
cat.say();
racoon.say();
return 0;
}
随着列表变得更大(比方说,超过 100 个元素),这种技术有助于避免过多的复制粘贴。
资料来源: https : //en.wikipedia.org/wiki/X_Macro
另请参见: X-macros
如果在使用 LIST
之前定义一个不匹配的 X
并不符合你的喜好,你也可以将宏名称作为参数传递:
#define LIST(MACRO) \
MACRO(dog) \
MACRO(cat) \
MACRO(racoon)
现在,你明确指定在扩展列表时应使用哪个宏,例如
#define FORWARD_DECLARE_ANIMAL(name) Animal name;
LIST(FORWARD_DECLARE_ANIMAL)
如果每次调用 MACRO
都应该采用额外的参数 - 相对于列表是常量,可以使用可变参数宏
//a walkaround for Visual studio
#define EXPAND(x) x
#define LIST(MACRO, ...) \
EXPAND(MACRO(dog, __VA_ARGS__)) \
EXPAND(MACRO(cat, __VA_ARGS__)) \
EXPAND(MACRO(racoon, __VA_ARGS__))
第一个参数由 LIST
提供,而其余参数由用户在 LIST
调用中提供。例如:
#define FORWARD_DECLARE(name, type, prefix) type prefix##name;
LIST(FORWARD_DECLARE,Animal,anim_)
LIST(FORWARD_DECLARE,Object,obj_)
将扩大到
Animal anim_dog;
Animal anim_cat;
Animal anim_racoon;
Object obj_dog;
Object obj_cat;
Object obj_racoon;