C++高级宏操作
C++高级宏操作
最近在看一个c++各数据类型和 JSON 或 xml 互转的库,重点阅读了其中宏的编写
1 | // 结构体格式如下 |
1 |
结构体中的变量数目不定,采用可变参数宏:
...
和__VA_ARGS__
配合使用,...
处填充的内容将填充到___VA_ARGS__
处
__VA_ARGS__
替换最后一个具体参数后所有内容包括逗号等
当然c++并不提倡使用可变参数
1 |
1 |
|
从这里开始可以看出XPACK已经被展开成了一个静态常量和两个函数,x_PACK_N()
被包在函数内部
1 |
很离谱第一次看到这种操作,算是奇技淫巧了,分析一下做了什么
举个例子:x_PACK_N(L,A, myA, myY)
扩展成X_PACK_COUNT(L, A, myX, myY, 一坨)(ACTION, __VA_ARGS__)
X_PACK_COUNT(L, A, myX, myY, -99, 一坨, _3, _2, _1)
X_PACK_COUNT(L, A, _99, _98, 一坨, _2, _1, N)
N
获取到_2
这个宏相当于是一个截取功能,理解成一个窗口
这一步的结果是X_PACK_L1_2(X_PACK_L1_DECODE, __VA_ARGS__)
注意:此方法适用于gcc,msvc中需要再添加一个宏#define EXPAND(...) __VA_ARGS__
,并且包含在X_PACK_COUNT()
之外
1 |
后面经过几步简单的变换转换成
1 | X_PACK_L1_DECODE(A(uid, "id")) X_PACK_L1_DECODE(O(name)) |
再来看一下X_PACK_L1_DECODE
1 | /////////////////////////// XPACK ///////////////////////////// |
很明显可以看出:用##
来实现switch逻辑
X_PACK_L1_DECODE(A(uid, "id"))
扩展成{X_PACK_L1_DECODE_A(uid, "id")}
后面的操作大同小异,经过几次扩展后从转为N2同时L1转为L2再转成X_PACK_ACT
类型的宏,最后由如下的宏转换成最终代码
1 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ decode act ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.