[Linux] 在 C/C++ 裡面使用 ## 和 __VA_ARGS__ 寫巨集指令
今天寫了一段 C 的程式,想要建立一個 STL map,
裡面每個不同的 mode 會有其對應的 bool 陣列,所以一開始寫得像這樣:
bool arrayMode0[] = { false }; bool arrayMode1[] = { false, true }; bool arrayMode2[] = { true, false }; bool arrayMode3[] = { true }; mapResult[0] = std::list<bool>(arrayMode0, arrayMode0+sizeof(arrayMode0)/sizeof(arrayMode0[0])); mapResult[1] = std::list<bool>(arrayMode1, arrayMode1+sizeof(arrayMode1)/sizeof(arrayMode1[0])); mapResult[2] = std::list<bool>(arrayMode2, arrayMode2+sizeof(arrayMode2)/sizeof(arrayMode2[0])); mapResult[3] = std::list<bool>(arrayMode3, arrayMode3+sizeof(arrayMode3)/sizeof(arrayMode3[0]));
但是程式碼的重覆性太高了….
當然也可以考慮用函式來 refactor,不過另一種方法是利用巨集指令 (macro)~
如下例,我們定義了一個 ADD_MODE 的巨集指令:
#define ADD_MODE(mode, ...) \ bool arrayMode##mode[] = { __VA_ARGS__ }; \ mapResult[mode] = std::list<bool>(arrayMode##mode, arrayMode##mode+sizeof(arrayMode##mode)/sizeof(arrayMode##mode[0]));
上面用到了 ## 來將 mode 和前面的 arrayMode 組成一個字串,
所以如果 mode 是 0 的時候就會組出 arrayMode0~
我們還在 ADD_MODE() 的參數裡用上了 … 這種變動型的參數,
這樣就可以在巨集定義裡面,使用 __VA_ARGS__ 來取得所有剩下的參數 (gcc 限定),
例如呼叫 ADD_MODE(1, a, b, c) 的話,__VA_ARGS__ 就會包含 a, b, c 三個參數~
定義好巨集之後,下面的巨集指令就可以定義出最一開始的程式了:
ADD_MODE(0, false); ADD_MODE(1, false, true); ADD_MODE(2, true, false); ADD_MODE(3, true);
參考資料:
(本頁面已被瀏覽過 716 次)