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"

如果您需要使用多个不同的宏而不只是IDENTITY.

我不是 100% 确定任意数量的参数是什么意思,但是如果你想IDENTITY一次调用两个参数而不是一个,你可以更改底部宏以使用BOOST_PP_MULBOOST_PP_INC访问“2n”th 和元组的第“2n+1”个元素,然后在调用中只调用宏的一半次数REPEAT

于 2014-10-20T21:27:45.753 回答