次のようにgetメソッドとsetメソッドを持つshared_ptrオブジェクトxがあります。
x->a_value();
x->set_a_value();
x->b_value();
x->set_b_value();
マクロを定義しようとすると:
#define MAC(type) \
x->set_##type##_value(val);
MAC(a)
それはうまくいきますが、私がそうするとき:
#define MAC(type) \
x->##type##_value();
MAC(a)
次のコンパイルエラーが発生します:pasting formed '->a', an invalid preprocessing token
プリプロセッサは「トークン」で動作します-名前と演算子が好きです。
_##
_演算子は、小さい部分を貼り付けて新しいトークンを作成します。最初の例では、_set_##type##_value
_は_set_a_value
_になります。これは有効なトークンです。
2番目の例では、_->##type##_value
_は_->a_value
_になります。これは、有効なプリプロセッサトークンnotです。それは2つのトークンであるべきです。
行x->type##_value();
を作成するだけで機能します。個別のトークンx
、_->
_、_a_value
_、_(
_、_)
_、および_;
_を取得します。
錫に書かれていること:->a
は、単一の有効なプリプロセッサトークンではありません。2つのトークンです。ここに貼り付ける必要はありません。
#define MAC(type) \
x->type##_value();
トークン貼り付け演算子(##
)は、2つのトークンを単一の有効トークンに連結するために使用されます。
書くとき
x->##type##_value();
最初に処理されるトークンはx
です。
次のトークンは、トークン->
とtype
を連結することにより形成されます。type
はa
であるため、連結の結果は->a
有効なトークンであるべきですが、そうではありません。
したがって、エラーが発生します:pasting formed '->a', an invalid preprocessing token
。
これを修正するには、単に書く
x->type##_value();
こちらです
解析される最初のトークンはx
です。
解析される次のトークンは->
です。
次のトークンは、トークンtype
(a
になります)とトークン_value
を連結して形成されます。これにより、有効なトークンであるa_value
が得られます。
次のトークンは(
です。
次のトークンは)
です。
最後のトークンは;
です。