3

I を使用BOOST_PPすると、次のコードに示すように、追加のトークンを使用してマクロを複数のコンマ区切りの値に展開できます。

ただし、引数がない場合は機能しません。

#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 に答える