私は現在、可変引数マクロに関する SO に関するかなりの数の質問を読んでいますが、最も単純な質問に誰も答えていないようです:
#define IDENTITY(x) x
#define IDENTITY_FOR_ALL(...) ???
すべての引数に対してIDENTITY_FOR_ALL
展開する方法はありますか? IDENTITY(X)
任意の数の引数も可能ですか?
私は現在、可変引数マクロに関する SO に関するかなりの数の質問を読んでいますが、最も単純な質問に誰も答えていないようです:
#define IDENTITY(x) x
#define IDENTITY_FOR_ALL(...) ???
すべての引数に対してIDENTITY_FOR_ALL
展開する方法はありますか? IDENTITY(X)
任意の数の引数も可能ですか?
可変個引数テンプレートの場合のように、可変個引数マクロのパック展開のようなものはありません。
ただし、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
ます。
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_MUL
しBOOST_PP_INC
、「2n」番目とタプルの "2n+1" 番目の要素を呼び出してから、呼び出しで半分の回数だけマクロをREPEAT
呼び出します。