使用BOOST_PP
,我可以使用一个额外的 token 将宏扩展为多个逗号分隔的值,如下面的代码所示。
但是,在无参数的情况下它不起作用。
#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) >;
我该如何实现?
最佳答案
此答案使用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__)
不会扩展为空。关于c++ - BOOST_PP在空序列情况下扩展序列,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29227073/