4

Boost.Preprocessor メタプログラムを書いていますが、次の問題があります。次のマクロを検討してください (これは問題を説明するために単純化したものです)。

#define ITERATION_IMPL(p1, p2, p3, p4) ((p1),(p2),(p3),(p4))
#define ITERATION(args) ITERATION_IMPL(hello, args(), world)

#define ARGS() a, b
ITERATION(ARGS)

前処理された出力は次のとおりです。

((hello),(a, b),(world),())

これは、args()が複数の引数に分割されていないことを示しています。標準に関する私の理解によれば、マクロの引数は置換リストに貼り付けられる前に完全に展開されます。したがって、次の展開シーケンスが期待されます。

ITERATION(ARGS)
ITERATION_IMPL(hello, ARGS(), world)
ITERATION_IMPL(hello, a, b, world)
((hello),(a),(b),(world))

それが私の望む結果です。ITERATION_IMPL呼び出し自体を変更せずにそれを達成するにはどうすればよいですか?

編集:それが不可能な場合(そして私はそう思う)、CまたはC ++の標準に基づいて説明してください。

4

1 に答える 1

3

が発生した場合ITERATION(ARGS)は、 を取りITERATION_IMPL(hello, args(), world)、 に置き換えargsARGSから再スキャンすると思います。ITERATION_IMPL(hello, ARGS(), world)の呼び出しですITERATION_IMPL。そのため、 を取り、(他のパラメーターと共に) に((p1),(p2),(p3),(p4))置き換えます。その後、再スキャンして解決します。あなたの場合、3つの引数を持つ4パラメータマクロを呼び出すことがなぜ機能するのかわかりません。p2ARGS()((hello),(a, b),(world),())

あなたができる

#define EVAL(X) X
#define ITERATION(args) ITERATION_IMPL EVAL((hello, args(), world))

それは を取りX、 を置換(hello, ARGS(), world)し、次に再スキャンして、 をARGS()に置き換えa, bます。結果のトークン文字列ITERATION_IMPL (hello, a, b, world)は、期待したとおりになります。

編集:GCCでテスト済み:)

編集: string が必要なことに気付きました((hello),(a),(b),(world))が、私の答えは stringITERATION_IMPL (hello, a, b, world)です。ITERATIONを呼び出した後に再スキャンすると、 に置き換わるためIERATION_IMPL EVAL((hello, ARGS(), world))だと思いますITERATION_IMPL (hello, a, b, wold)ITERATION_IMPL次に、これらの引数で呼び出すことができるようになったことを確認するために、別のスキャンが必要になります。そうITERATIONあるべき

#define ITERATION(args) EVAL(ITERATION_IMPL EVAL((hello, args(), world)))

X外側の forがにEVAL置き換えられると、再スキャンして の呼び出しにITERATION_IMPL EVAL((hello, args(), world))屈します。次に、呼び出しを再度スキャンし、本当に必要なシーケンスを生成します。ITERATION_IMPL (hello, a, b, world)EVALITERATION

于 2011-04-15T12:50:34.723 に答える