3

如何将参数反转为可变参数宏?例如,我想

#define REVERSE(...) ???

REVERSE(A,B,C) // expands to C,B,A

我的目标是将前后参数分开:

#define APPLY(FUN,...) FUN(__VA_ARGS__)

#define FRONT(FIRST,...) FIRST
#define REST(FIRST,...) __VA_ARGS__
#define MOST(...) APPLY(REVERSE,APPLY(REST,REVERSE(__VA_ARGS__)))
#define BACK(...) APPLY(FRONT,REVERSE_ARGUMENTS(__VA_ARGS__))

FRONT(A,B,C) // expands to A
REST(A,B,C) // expands to B,C
MOST(A,B,C) // expands to A,B
BACK(A,B,C) // expands to C
4

2 回答 2

2

Boost 预处理器库可以反转宏参数。不幸的是,它只能达到实现定义的最大参数列表长度。据我所知,不可能编写一个反转任意长参数列表的宏。

#include <boost/preprocessor.hpp>

#define REVERSE(...) BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_REVERSE(BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)))

#define APPLY(FUN,...) FUN(__VA_ARGS__)

#define FRONT(FIRST,...) FIRST
#define BACK(...) APPLY(FRONT,REVERSE(__VA_ARGS__))
#define REST(FIRST,...) __VA_ARGS__
#define MOST(...) APPLY(REVERSE,APPLY(REST,REVERSE(__VA_ARGS__)))
于 2013-01-24T15:13:00.327 回答
2

这是一个不使用任何外部库的答案。

没有办法在宏中反转任意长度的列表,因为编译器只通过代码,所以循环和递归实际上是不可能的。此代码适用于长度不超过 10 的列表。它可以扩展为更长的列表。

#define EXPAND(x) x

#define REVERSE_1(a) a
#define REVERSE_2(a,b) b,a
#define REVERSE_3(a,...) EXPAND(REVERSE_2(__VA_ARGS__)),a
#define REVERSE_4(a,...) EXPAND(REVERSE_3(__VA_ARGS__)),a
#define REVERSE_5(a,...) EXPAND(REVERSE_4(__VA_ARGS__)),a
#define REVERSE_6(a,...) EXPAND(REVERSE_5(__VA_ARGS__)),a
#define REVERSE_7(a,...) EXPAND(REVERSE_6(__VA_ARGS__)),a
#define REVERSE_8(a,...) EXPAND(REVERSE_7(__VA_ARGS__)),a
#define REVERSE_9(a,...) EXPAND(REVERSE_8(__VA_ARGS__)),a
#define REVERSE_10(a,...) EXPAND(REVERSE_9(__VA_ARGS__)),a
#define REVERSE1(N,...) EXPAND(REVERSE_ ## N(__VA_ARGS__))
#define REVERSE(N, ...) REVERSE1(N, __VA_ARGS__)

REVERSE 获取 va args 列表和 args 列表的长度并返回其反向。

要获取列表的长度,请使用此

#define _GET_NTH_ARG(_1, _2, _3, _4, _5, _6, _7, _9, _10, N, ...) N
#define NUM_ARGS(...) EXPAND(_GET_NTH_ARG(__VA_ARGS__,9,8,7,6,5,4,3,2,1,0))

我将它与需要使用 EXPAND 的 msvc2015 一起使用。如果您使用的是 gcc/g++,它应该可以在没有 EXPAND 的情况下工作。

于 2018-05-16T12:49:51.397 回答