3

使用BOOST_PPI 可以将宏扩展为带有附加标记的多个逗号分隔值,如下面的代码所示。

但是,它在没有参数的情况下不起作用。

#define BOOST_PP_VARIADICS
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/seq/for_each_i.hpp>
#include <boost/preprocessor/variadic/to_seq.hpp>

#define ADD_TOKEN(r, token, i, e) \
    BOOST_PP_COMMA_IF(i) token(e)

#define WRAP(...) \
    BOOST_PP_SEQ_FOR_EACH_I(ADD_TOKEN, decltype, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))

#define MACRO(fmt, ...) \
    Template<WRAP(__VA_ARGS__)>

MACRO("");
MACRO("", 0);
MACRO("", 0, 1);

编译时的输出gcc -E main.cpp

Template< decltype() >;
Template< decltype(0) >;
Template< decltype(0) , decltype(1) >;

如何MACRO在没有__VA_ARGS__参数的情况下将调用扩展到 null?

也就是说,我希望输出为:

Template< >;
Template< decltype(0) >;
Template< decltype(0) , decltype(1) >;

我怎样才能做到这一点?

4

1 回答 1

3

这个答案使用 GNU 扩展。你在评论中说你可以接受。

您可以使用:当且仅当省略可变参数时,BOOST_PP_TUPLE_SIZE((, ## __VA_ARGS__))它才会给您。1

模板有点棘手,因为它们可以包含不带括号的逗号,这在宏参数中使用时会引起混淆。以这样的方式编写它需要一些工作,即WRAP宏仅在完成后才展开BOOST_PP_IF

#define MACRO(fmt, ...) \
    Template< \
    BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_SIZE((,##__VA_ARGS__)), 1), \
        BOOST_PP_EXPAND, WRAP) (__VA_ARGS__) \
    >

注意:我BOOST_PP_EXPAND在空的情况下使用,因为BOOST_PP_EXPAND(__VA_ARGS__)会扩展为空。

于 2015-03-24T08:46:21.990 回答