我现在阅读了很多关于可变参数宏的问题,但似乎并没有人回答最简单的问题:
#define IDENTITY(x) x
#define IDENTITY_FOR_ALL(...) ???
有没有办法让IDENTITY_FOR_ALL
扩展到IDENTITY(X)
所有参数?是否也可以使用任意数量的参数?
答案 0 :(得分:3)
对于可变参数宏没有包扩展,因为存在可变参数模板。
您可以使用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"
Demo。 用逗号:
#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"
Demo。
使用g++ -std=c++11 -E -P file
检查预处理器输出。
答案 1 :(得分: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}执行此操作,那么将此变为一个更通用的宏,将宏调用以及单个参数列表逐个传递将会非常简单明了。 }。
我不是100%肯定你的意思是任意数量的参数,但如果你想一次用两个参数而不是一个参数调用IDENTITY
,你可以改变底部的宏来使用{ {1}}和IDENTITY
访问元组的“2n”和“2n + 1”元素,然后在BOOST_PP_MUL
调用中调用宏的次数只有一半。