BOOST_PP expand sequence in the empty sequence case

我怕爱的太早我们不能终老 提交于 2021-02-08 02:58:30

问题


Using BOOST_PP I can expand a macro into multiple comma separated values with an additional token, as can be seen in the below code.

However, it doesn't work in the no-argument case.

#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);

The output when compiling with gcc -E main.cpp is

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

How can I get calls to MACRO with no __VA_ARGS__ arguments expand to null?

That is, I'd like the output to be:

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

How can I achieve this?


回答1:


This answer uses a GNU extension. You stated in the comments that you're okay with that.

You can use BOOST_PP_TUPLE_SIZE((, ## __VA_ARGS__)): it will give you 1 if and only if the variadic arguments are omitted.

Templates are a bit tricky in that they can contain unparenthesised commas, which cause confusion when used in macro arguments. It takes a bit of work to write it in such a way that the WRAP macro is only expanded after BOOST_PP_IF has finished already:

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

Note: I'm using BOOST_PP_EXPAND in the empty case, because BOOST_PP_EXPAND(__VA_ARGS__) will expand to nothing.



来源:https://stackoverflow.com/questions/29227073/boost-pp-expand-sequence-in-the-empty-sequence-case

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!