現在的位置: 首頁 > 黃專家專欄 > 正文

奇技淫巧 – C/C++ 宏自身迭代

2014年10月30日 黃專家專欄 ⁄ 共 1924字 ⁄ 字型大小 評論關閉

boost 中包含了許多奇技淫巧的代碼,這裡分析宏的自身迭代

以這樣的宏代碼調用

1
BOOST_PP_ENUM_PARAMS(4, typename T)

它的宏展開為

1
typename T0 , typename T1 , typename T2 , typename T3

這在boost中被多用於簡化代碼量 比如 boos::function 中

下面來分析這類宏的具體實現

宏1:

1
#define BOOST_PP_ENUM_PARAMS(count, param) BOOST_PP_REPEAT(count, BOOST_PP_ENUM_PARAMS_M, param)

首先看看 BOOST_PP_ENUM_PARAMS_M 的作用

宏2:

1
#define BOOST_PP_REPEAT BOOST_PP_CAT(BOOST_PP_REPEAT_, BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4))

由宏2,可以看出,宏1展開為

1
BOOST_PP_CAT(BOOST_PP_REPEAT_, BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4))(count, BOOST_PP_ENUM_PARAMS_M, param)

BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4) 其實就是 1,這個是一個定值,在目前,我們不必去深究 那麼, BOOST_PP_CAT 就可以展開為

1
BOOST_PP_REPEAT_1(count, BOOST_PP_ENUM_PARAMS_M, param)

BOOST_PP_REPEAT_1 是一個非常簡單的迭代宏

1
2
3
4
5
6
7
# define BOOST_PP_REPEAT_1(c, m, d) BOOST_PP_REPEAT_1_I(c, m, d)
# define BOOST_PP_REPEAT_1_I(c, m, d) BOOST_PP_REPEAT_1_ ## c(m, d)
# define BOOST_PP_REPEAT_1_0(m, d)
# define BOOST_PP_REPEAT_1_1(m, d) m(2, 0, d)
# define BOOST_PP_REPEAT_1_2(m, d) BOOST_PP_REPEAT_1_1(m, d) m(2, 1, d)
# define BOOST_PP_REPEAT_1_3(m, d) BOOST_PP_REPEAT_1_2(m, d) m(2, 2, d)
... ...

所以

1
BOOST_PP_REPEAT(count, BOOST_PP_ENUM_PARAMS_M, param)

展開就等於

1
2
3
4
BOOST_PP_ENUM_PARAMS_M(2, 0, param)
BOOST_PP_ENUM_PARAMS_M(2, 1, param)
... ...
BOOST_PP_ENUM_PARAMS_M(2, count - 1, param)

BOOST_PP_ENUM_PARAMS_M 自然也是一個宏

1
# define BOOST_PP_ENUM_PARAMS_M(z, n, param) BOOST_PP_COMMA_IF(n) param ## n

所以就有

1
2
BOOST_PP_ENUM_PARAMS_M(2, 0, param) // 展開 第一個參數不要, 其實這個參數被用於優化的目的
BOOST_PP_COMMA_IF(0) param ## 0

BOOST_PP_COMMA_IF 是一個這樣的宏,如果參數非0,那麼列印出逗號,否則就不列印逗號

1
2
3
4
5
6
7
8
9
10
11
12
13
#define BOOST_PP_COMMA_IF(cond) BOOST_PP_IF(cond, BOOST_PP_COMMA, BOOST_PP_EMPTY)()
#define BOOST_PP_IF(cond, t, f) BOOST_PP_IIF(BOOST_PP_BOOL(cond), t, f)
#define BOOST_PP_IIF(bit, t, f) BOOST_PP_IIF_I(bit, t, f)
#define BOOST_PP_IIF_I(bit, t, f) BOOST_PP_IIF_ ## bit(t, f)
# define BOOST_PP_IIF_0(t, f) f
# define BOOST_PP_IIF_1(t, f) t
#define BOOST_PP_BOOL(x) BOOST_PP_BOOL_I(x)
# define BOOST_PP_BOOL_I(x) BOOST_PP_BOOL_ ## x
# define BOOST_PP_BOOL_0 0
# define BOOST_PP_BOOL_1 1
# define BOOST_PP_BOOL_2 1
... ...
# define BOOST_PP_BOOL_256 1

可以看出,宏多用窮舉

抱歉!評論已關閉.