Boost预处理器未展开

Boost preprocessor not expanding

本文关键字:处理器 预处理 Boost      更新时间:2023-10-16

我有以下代码:

#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没有展开?

再次传递此输出将扩展预期结果。

编辑:经过大量的搜索,我读到一个宏如果调用两次就不会扩展,我想这就是为什么。

编辑:我应该使用PP_SEQ_FOR_EACH_I,R不应该用作下标。

BOOST_PP_SEQ_FOR_EACH不可重入。Boost.PP中只有少数宏是可重入的(BOOST_PP_FORBOOST_PP_WHILEBOOST_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) ())
)
#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) ())
)