2013-02-06 62 views
2

我見過幾個問題,要求對變量FOR_EACH宏進行變化。不幸的是,所提供的答案與VC++ 10不兼容,因爲它將__VA_ARGS __作爲一個參數擴展到另一個宏時。請有人提供一個C++ 11兼容(因此向前兼容)的版本,仍然適用於VC++ 10。也許使用經常提到的「解決方法」,#define EXPAND(x) x,但是我不知道把這個放在哪裏以便獲得,例如,後者的一般部分this answer可以在VC++ 10中工作。預處理器可變參數FOR_EACH宏與MSVC++兼容10

爲了澄清,預期的行爲是FOR_EACH(x, a, b, ...)產生x(a) x(b), ...,其中x是另一個宏。

+0

提供的答案在哪裏?請鏈接到您提到的問題。 – liori

+0

會這麼做,我很難再找到他們。同時,請在問題第一段末尾看到相關答案。 – Dylan

回答

5

現在已經清楚地知道VC++ 10編譯器的bug是如何工作的,我可以根據this answer的後半部分自己想出一個這樣的宏。

#define EXPAND(x) x 
#define FOR_EACH_1(what, x, ...) what(x) 
#define FOR_EACH_2(what, x, ...)\ 
    what(x);\ 
    EXPAND(FOR_EACH_1(what, __VA_ARGS__)) 
#define FOR_EACH_3(what, x, ...)\ 
    what(x);\ 
    EXPAND(FOR_EACH_2(what, __VA_ARGS__)) 
#define FOR_EACH_4(what, x, ...)\ 
    what(x);\ 
    EXPAND(FOR_EACH_3(what, __VA_ARGS__)) 
#define FOR_EACH_5(what, x, ...)\ 
    what(x);\ 
    EXPAND(FOR_EACH_4(what, __VA_ARGS__)) 
#define FOR_EACH_6(what, x, ...)\ 
    what(x);\ 
    EXPAND(FOR_EACH_5(what, __VA_ARGS__)) 
#define FOR_EACH_7(what, x, ...)\ 
    what(x);\ 
    EXPAND(FOR_EACH_6(what, __VA_ARGS__)) 
#define FOR_EACH_8(what, x, ...)\ 
    what(x);\ 
    EXPAND(FOR_EACH_7(what, __VA_ARGS__)) 
#define FOR_EACH_NARG(...) FOR_EACH_NARG_(__VA_ARGS__, FOR_EACH_RSEQ_N()) 
#define FOR_EACH_NARG_(...) EXPAND(FOR_EACH_ARG_N(__VA_ARGS__)) 
#define FOR_EACH_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N 
#define FOR_EACH_RSEQ_N() 8, 7, 6, 5, 4, 3, 2, 1, 0 
#define CONCATENATE(x,y) x##y 
#define FOR_EACH_(N, what, ...) EXPAND(CONCATENATE(FOR_EACH_, N)(what, __VA_ARGS__)) 
#define FOR_EACH(what, ...) FOR_EACH_(FOR_EACH_NARG(__VA_ARGS__), what, __VA_ARGS__) 

實例:

#define callMember(o, f) o.f(); 
#define callMember_o(f) callMember(o, f) 
FOR_EACH(callMember_o, doSomething, doSomethingElse); 

相同

o.doSomething(); o.doSomethingElse(); 

這個解決方案是在鏈接的回答相似,不同之處在於在FOR_EACH(what, x, ...)當零長度可變參數的參數列表用一個元素調用會導致一個虛假逗號,使FOR_EACH_NARG計數2個參數而不是1個參數,並使用EXPAND宏解決方法。

VC++ 10中的錯誤是,如果__VA_ARGS__被傳遞給可變宏的定義內的宏,它會在替換到宏後計算,導致多個逗號分隔的參數被視爲一個。要解決此問題,必須延遲參數評估,直到__VA_ARGS__被替換爲止,方法是將宏調用包裝爲EXPAND,強制將宏調用評估爲字符串,用__VA_ARGS__替代。只有在EXPAND被替換爲被調用的宏之後,可變參數才被替換。

P.S.如果有人能提出一種方法來爲N更大的值緊密生成FOR_EACH_N宏,我將不勝感激。

+0

有一個版本,這是C99兼容?我收到如下錯誤:警告:ISO C99需要使用其餘參數 –