まず、N_ X
とN_X
の間に異なるがあります。最初は2つのトークンです。 1つのトークンを形成するには、トークン貼り付け演算子##
を使用する必要がありますが、この演算子は、マクロ展開を阻害するので、この:そのはM(a)
なくN_
をペーストしようとしているので、
M(a) ## X //Compiler error can't paste ')' and X
は、コンパイルエラーが発生します。
#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
ドラコシャ:私は同意しません。それらとその落とし穴を学ぶと、彼らは便利なツールになることができます。 – orlp
ナイトクラッカー:確かに、それらを学ぶ必要がありますが、実際にそれが最後のオプション(と私はあなたの答えをupvotedていない限り)を使用しないようにする必要があります – Drakosha