学习boost预编译的代码
来源:互联网 发布:nginx 80端口被占用 编辑:程序博客网 时间:2024/06/05 10:44
boost的代码很难看懂,从今天起每天看一点。
【1】在通过编译前,查看宏置换的结果,即方便解决编译问题,又方便分析代码,方法如下
#define STR(a) STR_I(a)
#define STR_I(a) #a
printf(STR(SOME_MARCO(xxx)));
再用此方法看看最难懂的宏之一 BOOST_PP_AUTO_REC的置换结果(注意包含对应的头文件)
printf(STR(BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4)));
printf("\n");
printf(STR(BOOST_PP_AUTO_REC(BOOST_PP_WHILE_P, 256)));
printf("\n");
printf(STR(BOOST_PP_AUTO_REC(BOOST_PP_FOR_P, 256)));
printf("\n");
printf(STR(BOOST_PP_AUTO_REC(BOOST_PP_SEQ_FOLD_LEFT_P, 256)));
printf("\n");
打印出来的结果全是“1”,很意外,那么这个宏到底起什么作用呢?
猜测1:对输入的第一个参数进行校验,确定是有效的宏,避免编译器进入死循环什么的
猜测2:提高编译速度,减少宏置换时的递归深度
【2】BOOST_PP_WHILE宏的作用
BOOST_PP_WHILE 被置换成BOOST_PP_WHILE_1,看代码从这里看起,不要管那个BOOST_PP_AUTO_REC(BOOST_PP_WHILE_P, 256)
该宏需要三个参数,第一个是被称为pred的宏,负责生成循环结束条件;第二个是被称为op的宏,就是每次循环要执行的操作;第三个是被操
作的参数,格式为(a,b,c,d)中间可以有任意个元素,在boost中这种格式被称为tuple;该宏的返回值也是一个tuple。
宏pred和宏op都是调用者实现的,其格式有严格的要求。
pred的格式为MARCO_NAME(d,xy),参数d是循环执行次数的序号,起始序号为2;参数xy是一个tuple,其长度和WHILE宏的第三个参数相等;要
求返回一个整数,返回0时终止循环,返回1~256时的效果是一样的,都是继续循环。
op的格式为MARCO_NAME(d,xy),参数d是循环执行次数的序号;参数xy是一个tuple,长度和WHILE宏的第三个参数相等;要求返回一个tuple,
长度为WHILE宏的第三个参数相等。
以加法操作BOOST_PP_ADD(x,y)为例,首先生成长度为2的tuple(x,y),然后执行
BOOST_PP_WHILE( BOOST_PP_ADD_P, BOOST_PP_ADD_O, (x,y) )
宏BOOST_PP_ADD_P构造循环终止条件,简单地返回y的值
宏BOOST_PP_ADD_O将输入的(x,y)变成(x+1,y-1)
没循环一次,x的值加1,y的值减1,y变成零时结束循环,此时x变成x+y了,WHILE宏返回的结果是(x+y,0)
【3】BOOST_PP_WHILE的实现原理
# define BOOST_PP_WHILE_2(p, o, s) BOOST_PP_WHILE_2_C(BOOST_PP_BOOL(p(3, s)), p, o, s)
# define BOOST_PP_WHILE_2_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_3, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o,
BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(3, s))
BOOST_PP_IIF是条件判定分支,BOOST_PP_IF(c, A, B)在c不为0是返回A,在c为0是返回B,变成下面样子
# define BOOST_PP_WHILE_2_C(c, p, o, s)
if (c)
BOOST_PP_WHILE_3(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(3, s))
else
s BOOST_PP_TUPLE_EAT_3(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(3, s))
BOOST_PP_TUPLE_EAT_3的作用就是消掉输入的三个参数,变成下面样子
# define BOOST_PP_WHILE_2_C(c, p, o, s)
if (c)
BOOST_PP_WHILE_3(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(3, s))
else
s
上面if (c) 分支中,还有一个BOOST_PP_IF判断,判定结果肯定是true,变成下面样子
# define BOOST_PP_WHILE_2_C(c, p, o, s)
if (c)
BOOST_PP_WHILE_3(p, o, o(3, s))
else
s
综合起来,变成下面简单的形式
#define BOOST_PP_WHILE_2(p, o, s)
IF p(3,s)
BOOST_PP_WHILE_3(p, o, o(3,s))
ELSE
s
为什么不用递归的方式,而是写一大堆的BOOS_PP_WHILE_n?应该是怕递归不能正确地结束,编译时使编译器进入死循环。
- 学习boost预编译的代码
- 学习boost预编译的代码:查表法
- 学习boost预编译的代码:BOOST_PP_IS_EMPTY(X)
- vs查看预编译后的代码
- [Boost]_[使用预编译头文件解决引用boost后项目编译很慢的问题]
- 预编译语言学习
- VC预编译代码文件
- iphone 常用预编译代码
- 代码块和预编译
- 使用VS2005中.rc资源的预编译处理代码
- C/C++的预编译宏做成代码模版使用
- 解析Contiki系统protothread的预编译C代码
- VC的预编译头文件的学习
- 预编译的理解
- javaScript的预编译
- 预编译的作用
- 预编译的对象
- 预编译的过程
- Linux基础之如何创建用户
- HDU 4046 树状数组
- python笔记《5》
- iphone之轮换效果
- javascript 实现全部替换(replaceAll)
- 学习boost预编译的代码
- MFC中Timer的使用方法
- UIGestureRecognizer侦测使用者输入操作
- table二级菜单效果,雪花效果
- UITableView下拉刷新页面的实现(有框架)
- ChartDirector 5.0 for python 笔记【2】Simple Pie Chart
- UIImage的灰化处理
- 浅析Java抽象类和接口的比较
- UIImage具有渐变效果