【问题标题】:reverse the arguments to a variadic macro将参数反转为可变参数宏
【发布时间】:2012-12-31 05:02:57
【问题描述】:

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

#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

【问题讨论】:

    标签: c c-preprocessor c99 variadic-macros


    【解决方案1】:

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

    没有办法在宏中反转任意长度的列表,因为编译器只通过代码,所以循环和递归实际上是不可能的。此代码适用于长度不超过 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 的情况下工作。

    【讨论】:

      【解决方案2】:

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

      #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__)))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-22
        • 1970-01-01
        • 2011-09-11
        • 1970-01-01
        • 1970-01-01
        • 2013-05-21
        • 2011-08-18
        • 1970-01-01
        相关资源
        最近更新 更多