首先在N_ X
和N_X
之間有所不同。第一個是兩個令牌。爲了形成一個令牌,你必須使用標記粘貼操作##
,但該運營商抑制宏擴展,所以這樣的:
M(a) ## X //Compiler error can't paste ')' and X
導致編譯錯誤,因爲它試圖粘貼M(a)
而不是N_
。您可以允許宏通過使用宏一層額外的粘貼之前擴大(這實在是常用宏):
#define PRIMITIVE_CAT(x, y) x ## y
#define CAT(x, y) PRIMITIVE_CAT(x, y)
然而,在你的情況下,這仍然無法工作:
CAT(M(a), X) //expands to 0
這是因爲您正在使用對象宏而不是函數宏。如果您將其更改爲功能宏,它會工作,你怎麼想:
#define N_() 0
#define N_X() 1
#define M(a) N_
CAT(M(arg), X)() // expands to 1
M(arg)() // expands to 0
功能宏功能更強大,可以延遲他們的擴張。這裏是你如何能延緩他們一個掃描:
#define EMPTY()
#define DEFER(x) x EMPTY()
N_() //Expands to 0
DEFER(N_)() //Expands N_()
延遲宏展開這樣的是遞歸可在預處理器實現的途徑之一。
和宏一般都是邪惡的 – Drakosha
Drakosha:我會不同意。瞭解他們和他們的陷阱,他們可以成爲一個方便的工具。 – orlp
nightcracker:當然,你需要學習它們,但你應該儘量避免使用它們,除非它是最後一個選項(並且我upvoted你的答案) – Drakosha