5

私は現在、可変引数マクロに関する SO に関するかなりの数の質問を読んでいますが、最も単純な質問に誰も答えていないようです:

#define IDENTITY(x) x
#define IDENTITY_FOR_ALL(...) ???

すべての引数に対してIDENTITY_FOR_ALL展開する方法はありますか? IDENTITY(X)任意の数の引数も可能ですか?

4

2 に答える 2

5

可変個引数テンプレートの場合のように、可変個引数マクロのパック展開のようなものはありません。

ただし、Boost.Preprocessor (またはそのメソッド) を使用できます。

要素間にカンマを入れたくない場合は、

#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/variadic/to_seq.hpp>

#define ID_OP(_, func, elem) func(elem)
#define APPLY_TO_ALL(func, ...)                \
    BOOST_PP_SEQ_FOR_EACH(                     \
        ID_OP, func,                           \
        BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)  \
    )

// example call:

#define SomeTransformation(x) #x // stringize the argument

APPLY_TO_ALL(SomeTransformation, 1, 2, 3) // expands to "1" "2" "3"

デモ。カンマ付き:

#include <boost/preprocessor/seq/enum.hpp>
#include <boost/preprocessor/seq/transform.hpp>
#include <boost/preprocessor/variadic/to_seq.hpp>

#define ID_OP(_, func, elem) func(elem)
#define APPLY_TO_ALL(func, ...)               \
    BOOST_PP_SEQ_ENUM(                        \
    BOOST_PP_SEQ_TRANSFORM(                   \
        ID_OP, func,                          \
        BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__) \
    ))

// example call:

APPLY_TO_ALL(SomeTransformation, 1, 2, 3) // expands to "1", "2", "3"

デモ。でプリプロセッサの出力を確認しg++ -std=c++11 -E -P fileます。

于 2014-10-20T21:34:39.697 に答える
1

PP ソリューションが必要であると仮定すると、以下を使用できますBOOST_PP_REPEAT

//invoke IDENTITY_FOR_ALL_MACRO with each index and the given tuple
#define IDENTITY_FOR_ALL(...)                   \
    BOOST_PP_REPEAT(                            \
        BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),    \
        IDENTITY_FOR_ALL_MACRO,                 \
        BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__) \
    )

//use the index to access the right element of the passed tuple
#define IDENTITY_FOR_ALL_MACRO(z, n, data) \
    IDENTITY(BOOST_PP_TUPLE_ELEM(n, data))

IDENTITY_FOR_ALL(abc, 123, "woopee")
//translated to abc 123 "woopee"

だけでなくいくつかの異なるマクロでこれを行う必要がある場合、これを呼び出すマクロと単一の引数のリストを1つずつ渡すより一般的なマクロに変えることは、かなり簡単ですIDENTITY

IDENTITY任意の数の引数が何を意味するのか 100% はわかりませんが、一度に 1 つではなく 2 つの引数で呼び出したい場合は、一番下のマクロを変更して使用BOOST_PP_MULBOOST_PP_INC、「2n」番目とタプルの "2n+1" 番目の要素を呼び出してから、呼び出しで半分の回数だけマクロをREPEAT呼び出します。

于 2014-10-20T21:27:45.753 に答える