3

次のコードがあります。

#include <boost/preprocessor.hpp>

#define ARGS(r, data, elem) \
    BOOST_PP_COMMA_IF(BOOST_PP_SUB(r, 2)) \
    BOOST_PP_SEQ_ELEM(0, elem) BOOST_PP_SEQ_ELEM(1, elem)

#define DEF_FUN(name, args) void name(BOOST_PP_SEQ_FOR_EACH(ARGS,,args));

#define DEF_FUNCTIONS_ELEM(r, data, elem) DEF_FUN(BOOST_PP_SEQ_ELEM(0, elem), BOOST_PP_SEQ_ELEM(1, elem))

#define DEF_FUNCTIONS(funSeqs) \
    BOOST_PP_SEQ_FOR_EACH(DEF_FUNCTIONS_ELEM,, funSeqs)


DEF_FUNCTIONS_ELEM(2,, (fun0) (((int)(arg0))   ((char)(arg1))))

DEF_FUNCTIONS
(
    ((fun0) (((int)(arg0))   ((char)(arg1))))
    ((fun1) (((char)(arg0))  ((long)(arg1)) ((short)(arg2))))
    ((fun3) ())
)

これを Clang 3.2 または g++ 4.6.3 で前処理すると、次のようになります。

void fun0( int arg0 , char arg1 );

void fun0(BOOST_PP_SEQ_FOR_EACH(ARGS,,((int)(arg0)) ((char)(arg1)))); 
void fun1(BOOST_PP_SEQ_FOR_EACH(ARGS,,((char)(arg0)) ((long)(arg1)) ((short)(arg2)))); 
void fun3(BOOST_PP_SEQ_FOR_EACH(ARGS,,)); 

(わかりやすくするために改行を追加しました)

問題は、内部の BOOST_PP_SEQ_FOR_EACH が展開されないのはなぜですか?

この出力を再度渡すと、期待される結果が展開されます。

編集:多くの検索の後、マクロが2回呼び出されると展開されないことを読みました。それが理由だと思います。

編集: PP_SEQ_FOR_EACH_I を使用する必要がありました。R は添字として使用するためのものではありません。

4

2 に答える 2

4

BOOST_PP_SEQ_FOR_EACH再入可能ではありません。BOOST_PP_FORBoost.PP には、再入可能 ( 、BOOST_PP_WHILE、および)のマクロがわずかしかありませんBOOST_PP_REPEAT。ただし、次のように遅延式を使用することで回避できます。

#include <boost/preprocessor.hpp>

#define EXPAND(...) __VA_ARGS__
#define EMPTY()
#define DEFER(x) x EMPTY()
// An indirection macro to avoid direct recursion
#define BOOST_PP_SEQ_FOR_EACH_ID() BOOST_PP_SEQ_FOR_EACH

#define ARGS(r, data, elem) \
    BOOST_PP_COMMA_IF(BOOST_PP_SUB(r, 2)) \
    BOOST_PP_SEQ_ELEM(0, elem) BOOST_PP_SEQ_ELEM(1, elem)

// Defer BOOST_PP_SEQ_FOR_EACH_ID here
#define DEF_FUN(name, args) void name(DEFER(BOOST_PP_SEQ_FOR_EACH_ID)()(ARGS,,args));

#define DEF_FUNCTIONS_ELEM(r, data, elem) DEF_FUN(BOOST_PP_SEQ_ELEM(0, elem), BOOST_PP_SEQ_ELEM(1, elem))

// Add EXPAND here to apply another scan to expand the deferred expression
#define DEF_FUNCTIONS(funSeqs) \
    EXPAND(BOOST_PP_SEQ_FOR_EACH(DEF_FUNCTIONS_ELEM,, funSeqs))


DEF_FUNCTIONS
(
    ((fun0) (((int)(arg0))   ((char)(arg1))))
    ((fun1) (((char)(arg0))  ((long)(arg1)) ((short)(arg2))))
    ((fun3) ())
)
于 2013-03-28T14:01:10.700 に答える
1
#include <boost/preprocessor.hpp>

#define ARGS(r, data, index, elem) \
    BOOST_PP_SEQ_ELEM(0, elem) BOOST_PP_SEQ_ELEM(1, elem) BOOST_PP_COMMA_IF(BOOST_PP_NOT_EQUAL(index, BOOST_PP_DEC(data)))

#define DEF_FUN(name, args) void name(BOOST_PP_SEQ_FOR_EACH_I(ARGS,BOOST_PP_SEQ_SIZE(args),args));

#define DEF_FUNCTIONS_ELEM(r, data, elem) DEF_FUN(BOOST_PP_SEQ_ELEM(0, elem), BOOST_PP_SEQ_ELEM(1, elem))

#define DEF_FUNCTIONS(funSeqs) \
    BOOST_PP_SEQ_FOR_EACH(DEF_FUNCTIONS_ELEM,, funSeqs)


DEF_FUNCTIONS_ELEM(2,, (fun0) (((int)(arg0))   ((char)(arg1))))

DEF_FUNCTIONS
(
    ((fun0) (((int)(arg0))   ((char)(arg1))))
    ((fun1) (((char)(arg0))  ((long)(arg1)) ((short)(arg2))))
    ((fun3) ())
)
于 2013-03-27T23:41:18.043 に答える