学习boost预编译的代码:查表法

本文介绍了Boost库中利用查表法实现的宏,如BOOST_PP_BOOL、BOOST_PP_INC等,详细解释了查表法的原理,并通过例子展示了如何在宏替换过程中处理参数。同时探讨了BOOST_PP_IIF和BOOST_PP_TUPLE_ELEM这两个更复杂的查表法应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【1】用宏的技巧,查表法

查表法的作用是输入一个或多个参数,查表得到另一个参数,boost里面很多宏的实现都是查表法,例如

BOOST_PP_BOOL(x) 将整数x转换成0或1

BOOST_PP_INC(x) 将返回x+1

BOOST_PP_DEC(x)返回x-1

BOOST_PP_BITAND(x,y) 对两个bit进行与操作

BOOST_PP_BITNOR(x,y) 对两个bit进行或非操作

BOOST_PP_BITOR(x,y) 对两个bit进行或操作

BOOST_PP_BITXOR(x,y) 对两个bit进行异或操作

BOOST_PP_COMPL(x) 对一个bit进行取反操作

查表法的原理如下

#define MARCO_NAME(x)       MARCO_NAME_I (x)

#define MARCO_NAME_I (x)   MARCO_ ## x

#define MARCO_x y      (这里不是一个宏,要定义一大堆的宏,对每一个可能的输入值x,将MARCO_x定义成要返回的值y)

 

为什么不省略宏MARCO_NAME_I,直接定义成 #define MARCO_NAME(x)      MARCO_ ## x

回答这个问题,需要了解宏置换的具体过程(就像函数调用过程一样)。不同的书上有不同的解释,本人的解释如下:

调用一个带参数的宏时,要输入一堆的参数,编译其在置换宏前,对每个参数都触发置换过程,用一个表保存每个参数置换前的值和置换后的值。在置换宏时,如果对参数使用了#或##或#@运算符,那么替换成参数置换前的值;否则替换成参数置换后的值。

例如

#define N 100

#define M(a) a, #a

M(N);

在置换宏M前,得到一个参数列表

参数名=a,置换前的值=N,置换后的值=100

置换宏时,逗号前面的a被替换成100,#后面的a被替换成N

M(N)被置换成 100,"N"

VC++编译器没有遵循标准规定,将##运输符两边的参数替换成参数置换后的值。看似能节省代码,实际上遇到下面宏时就不知道怎么翻译了 #define M(a,b,c) # a ## b ## c,标准没有规定#和##运输符的优先级,也没有规定##运算符是左结合、还是右结合

 

 

【2】BOOST_PP_IF和BOOST_PP_IIF的本质也是查表法
上面的查表法都是输入一个常数,得到另一个常数,更高级的技巧是输入一个常数和一些变量,返回处理过的变量。
BOOST_PP_IIF的实现如下,bit允许输入0或1,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

【3】BOOST_PP_TUPLE_ELEM查的是一个二维表
该宏从一个tuple中获取特定位置的元素,相当于根据下标从数组中取元素。
BOOST_PP_TUPLE_ELEM(size, index, tuple)
参数size是一个整数,标明tuple的长度
参数index是下标,从0开始
参数tuple是类似(a,b,c,d)格式的结构
BOOST_PP_TUPLE_ELEM (4, 2, (a,b,c,d)) 返回结果是c

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值