我有以下boost预处理器宏来生成函数
extern "C" EXPORT out name(BOOST_PP_SEQ_FOR_EACH_I(PARAMETER_LIST, 0, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)))
除非__VA_ARGS__
为空,否则效果很好。经过一些搜索后,我找到了一种方法,使用BOOST_PP_VARIADIC_SIZE计算__VA_ARGS__
中参数的数量。经过一番思考后我写了这个MACRO:
extern "C" EXPORT out name(BOOST_PP_IF(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), BOOST_PP_SEQ_FOR_EACH_I(PARAMETER_LIST, 0, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)), void))
我认为这应该有效,但是我一直收到以下警告
warning C4002: too many actual parameters for macro 'BOOST_PP_IIF_1'
虽然这是一个警告,它似乎仍然打破了预处理器。传递多个参数时,它只会处理第一个参数。我觉得这很奇怪,怎么会加入这个如果打破一切都是如此奇怪的方式?我已经检查了逗号和括号一百次,但看起来很好。我该如何修复这个预处理器?
http://www.boost.org/doc/libs/1_54_0/libs/preprocessor/doc/ref/if.html
编辑:此回归似乎相关:https://svn.boost.org/trac/boost/ticket/8606
答案 0 :(得分:1)
实现:
#include <boost/preprocessor.hpp>
// based on the: http://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments
#define __ARG16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) _15
#define __HAS_COMMA(...) __ARG16(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
#define __TRIGGER_PARENTHESIS_(...) ,
#define __PASTE5(_0, _1, _2, _3, _4) _0 ## _1 ## _2 ## _3 ## _4
#define __IS_EMPTY_CASE_0001 ,
#define __IS_EMPTY(_0, _1, _2, _3) __HAS_COMMA(__PASTE5(__IS_EMPTY_CASE_, _0, _1, _2, _3))
#define TUPLE_IS_EMPTY(...) \
__IS_EMPTY( \
/* test if there is just one argument, eventually an empty one */ \
__HAS_COMMA(__VA_ARGS__), \
/* test if _TRIGGER_PARENTHESIS_ together with the argument adds a comma */ \
__HAS_COMMA(__TRIGGER_PARENTHESIS_ __VA_ARGS__), \
/* test if the argument together with a parenthesis adds a comma */ \
__HAS_COMMA(__VA_ARGS__ (/*empty*/)), \
/* test if placing it between _TRIGGER_PARENTHESIS_ and the parenthesis adds a comma */ \
__HAS_COMMA(__TRIGGER_PARENTHESIS_ __VA_ARGS__ (/*empty*/)) \
)
#define __GEN_EMPTY_ARGS(...) \
void
#define __GEN_NONEMPTY_ARGS_CB(unused, data, idx, elem) \
BOOST_PP_COMMA_IF(idx) elem arg##idx
#define __GEN_NONEMPTY_ARGS(seq) \
BOOST_PP_SEQ_FOR_EACH_I( \
__GEN_NONEMPTY_ARGS_CB \
,~ \
,seq \
)
#define GEN(out, name, ...) \
extern "C" EXPORT out name( \
BOOST_PP_IF( \
TUPLE_IS_EMPTY(__VA_ARGS__) \
,__GEN_EMPTY_ARGS \
,__GEN_NONEMPTY_ARGS \
)(BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__))) \
) {}
// test
GEN(void, finc0, int, char, long)
GEN(void, func1)
输出:
extern "C" EXPORT void finc0( int arg0 , char arg1 , long arg2 ) {}
extern "C" EXPORT void func1( void ) {}