C++ boost.preprocessor自動定義枚舉

想定義一個宏,實現目的以下:linux

ZME_PP_ENUM_DEF(name, ...);測試

展開以後是:spa

enum    E_name編譯

{循環

E_name_NULL,語法

E_name_0,方法

E_name_1,error

.......co

E_name_COUNTvs2013

};

例如:ZME_PP_ENUM_DEF(TST, A, B, C, D);

展開以後是:

enum    E_TST

{

E_TST_NULL,

E_TST_A,

E_TST_B,

E_TST_C,

E_TST_D,

E_TST_COUNT

};

具體的實現代碼以下:


#define ZME_LOOP_PRED_4(r, state) \
    BOOST_PP_LESS(\
    BOOST_PP_TUPLE_ELEM(4, 0, state), \
    BOOST_PP_TUPLE_ELEM(4, 1, state) \
    )   \
    /**/

#define ZME_LOOP_OP_4(r, state) \
    (\
    BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(4, 0, state)), \
    BOOST_PP_TUPLE_ELEM(4, 1, state), \
    BOOST_PP_TUPLE_ELEM(4, 2, state), \
    BOOST_PP_TUPLE_ELEM(4, 3, state) \
    ) \
    /**/
#define  ZME_LOOP_FOR4(opt, arg, ...)    BOOST_PP_FOR((0, BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), BOOST_PP_VARIADIC_TO_LIST(__VA_ARGS__), arg), ZME_LOOP_PRED_4, ZME_LOOP_OP_4, opt)/**/

/*定義循環方法:*/

方法1:
#define         ZME_PP_ENUM_DEF_FOR_DO(r, state)        BOOST_PP_CAT(BOOST_PP_LIST_AT((BOOST_PP_TUPLE_ELEM(4, 3, state),BOOST_PP_NIL), 0),BOOST_PP_LIST_AT(BOOST_PP_TUPLE_ELEM(4, 2, state), BOOST_PP_TUPLE_ELEM(4, 0, state))),/**/

方法2:
#define         ZME_PP_ENUM_DEF_FOR_DO(r, state)        BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(4, 3, state), \
                                                        BOOST_PP_LIST_AT(BOOST_PP_TUPLE_ELEM(4, 2, state), BOOST_PP_TUPLE_ELEM(4, 0, state))),/**/

方法2中正常理解BOOST_PP_TUPLE_ELEM(4, 3, state)展開以後就是arg,可是這種方法在linux系統(我用的是KALI2.0)下是沒問題的,可是在VS2013下,編譯錯誤:

錯誤    1    error C2143: 語法錯誤 : 缺乏「}」(在「(」的前面)   
錯誤    2    error C2143: 語法錯誤 : 缺乏「;」(在「<L_TYPE_raw>」的前面)   
錯誤    3    error C2059: 語法錯誤:「<L_TYPE_raw>」   
錯誤    4    error C2143: 語法錯誤 : 缺乏「;」(在「}」的前面)   
錯誤    5    error C2065: 「E_TST_NULL」: 未聲明的標識符   
.........

 

BOOST_PP_CAT在BOOST_PP_FOR中使用好像有問題。解決方法就是使用方法1,先把BOOST_PP_TUPLE_ELEM(4, 3, state)也就是arg轉化爲BOOST_PP_LIST,而後再取其第一個值。

/* 定義枚舉結構 */
#define         ZME_PP_ENUM_DEF(name, ...)        enum    E_##name    {                    \
                        E_##name##_NULL,                                                \
                        ZME_LOOP_FOR4(ZME_PP_ENUM_DEF_FOR_DO, E_##name##_, __VA_ARGS__)    \
                        E_##name##_COUNT                                                \
                        };/**/

/********************************************************************************/

/* OK, 這樣就能夠定義咱們的枚舉了。*/

ZME_PP_ENUM_DEF(TST, A, B, C, D);

printf("ZME_PP_ENUM_DEF: %d, %d, %d, %d, %d, %d\n", E_TST_NULL, E_TST_A, E_TST_B, E_TST_C, E_TST_D, E_TST_COUNT);

win8.1+vs201三、kali2.0測試經過。

相關文章
相關標籤/搜索