我现在阅读了很多关于可变参数宏的 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"
如果您需要使用多个不同的宏而不只是IDENTITY
.
我不是 100% 确定任意数量的参数是什么意思,但是如果你想IDENTITY
一次调用两个参数而不是一个,你可以更改底部宏以使用BOOST_PP_MUL
和BOOST_PP_INC
访问“2n”th 和元组的第“2n+1”个元素,然后在调用中只调用宏的一半次数REPEAT
。