C++ boost.preprocessor自动定义枚举
C++ boost.preprocessor自动定义枚举
百之姓 发表于2年前
C++ boost.preprocessor自动定义枚举
  • 发表于 2年前
  • 阅读 35
  • 收藏 1
  • 点赞 2
  • 评论 0
摘要: 想定义一个宏,实现目的如下: ZME_PP_ENUM_DEF(name, ...); 展开之后是: enum    E_name { E_name_NULL, E_name_0, E_name_1, ....... E_name_COUNT }; 例如: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 }; 发现boost.1.57.0中的一个BUG

想定义一个宏,实现目的如下:

ZME_PP_ENUM_DEF(name, ...);

展开之后是:

enum    E_name

{

E_name_NULL,

E_name_0,

E_name_1,

.......

E_name_COUNT

};

例如: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+vs2013、kali2.0测试通过。

 

 

共有 人打赏支持
粉丝 0
博文 1
码字总数 453
×
百之姓
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: