2017-10-28 10 views
1

でマクロのための十分な実際のパラメータがこのC4003:C++

#define getFourth(_1,_2,_3, _4,...) _4 //select the 4th parameter 
#define some_type(x) type, x 

getFourth 
( some_type(1), 
    some_type(2), 
    some_type(3) 
) 

を見ていない私はそれがgetFourth(タイプ、1、タイプ、2型、3)ので、我々は2を選択したものに展開思いました(2は第4パラメータなので)。代わりに、私は警告"C4003 not enough actual parameters for macro 'getFourth"を得た。 getFourthは、最初の要素としてsome_type(1)を、第2要素としてsome_type(2)を、第3要素としてsome_type(3)を扱っているようです。それは少なくとも4つのパラメータを期待していたので、警告があります。誰かがそれを修正する方法を提案してもらえますか?

答えて

1
私は

(2が4番目のパラメータであるため)ので、我々は2を選択しなければならない(3、タイプ、1、タイプ、2、タイプ)それはgetFourthに展開思っマクロがどのように動作するかではないこと。さらに、拡張のための2つの機会があります:(1)引数置換の間、(2)それが起こった後の置換リストとの展開。引数置換の拡張は、マクロ内のパラメータが置換リスト内のパラメータに対応する場合にのみ発生し、そのパラメータは#演算子またはペースト(##)に関与する文字列ではありません。私たちが持っていた場合例えば

は、:そして、

#define foo(b,c) b c 
getFourth(some_type(1),some_type(2),some_type(3),foo(some_type,(4)),x) 

getFourthは現在5つのパラメータを持っているので、それが呼び出すことができます。拡張の最初のステップは引数の置換になります。 getFourthの置換リストは_4であり、1つのパラメータのみが記述されています。対応する引数はfoo(some_type,(4))です。 _4は貼り付けまたは文字列化されていないため、プロセッサはfoo(some_type,(4))と評価できます。その結果、some_type (4)になり、さらにtype, 4に拡張されます。今のところ_4の代わりにtype, 4が返されます。そして、我々は議論の代用で終わった。

type, 4となります。もう一度再スキャンしますが、このステップでは何も起こりません。しかしsome_type(1)some_type(2)、およびsome_type(3)だけでなくgetFourth前に評価されなかったことに注意してください、しかし、置換リストでは何がそれらを言及していないため、彼らは、すべてので評価されませんでした。

誰かがそれを修正する方法を提案できますか?

拡張したいものがgetFourthの引数1〜3である限り、それらは評価さえしません。しかし、あなたはこのただ、括弧内のリストを作ることができ、かつはその後は、私が上記のやったことに似トリック使って、マクロを適用します。

#define CALL(a,b) a b 
CALL(getFourth,(some_type(1),some_type(2),some_type(3))). 

さて、getFourth(some_type(1),some_type(2),some_type(3))CALLにちょうど引数は、両方のパラメータに言及します。したがって、引数の置換中にgetFourth自体が "評価する"(これはオブジェクトのようなマクロを呼び出すには不十分なのでそのまま残す)、aに入れられます。 (some_type(1),some_type(2),some_type(3))が評価され、bに入れられます。その評価は(type, 1,type, 2,type, 3)になります。だから、あなたはgetFourth (type, 1,type, 2,type, 3)となる。再スキャンが行われ、getFourthが期待する引数で呼び出されます。