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;