C++ X-macros X宏

示例

一种在编译时生成重复代码结构的惯用技术。

X宏由两部分组成:列表和列表的执行。

例:

#define LIST \
    X(dog)   \
    X(cat)   \
    X(racoon)

// 动物类{
//  上市:
//    无效的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-宏


如果X在使用之前定义与接缝无关的内容LIST与您的喜好无关,则也可以将宏名称作为参数传递:

#define LIST(MACRO) \
    MACRO(dog) \
    MACRO(cat) \
    MACRO(racoon)

现在,您明确指定在扩展列表时应使用哪个宏,例如

#define FORWARD_DECLARE_ANIMAL(name) Animal name;
LIST(FORWARD_DECLARE_ANIMAL)

如果每次调用MACRO都应采用其他参数-相对于列表为常数,则可以使用可变参数宏

//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;