宏元编程——技术——解决重入引起展开失败问题
来源:互联网 发布:python 2.7 安装 编辑:程序博客网 时间:2024/06/05 07:17
什么是宏重入?
宏在展开的时候,如果遇到同名的宏会终止展开,把同名的宏当成一个整体。
#define MY_CAT(p1,p2) MY_CAT_D(p1,p2)#define MY_CAT_D(p1,p2) p1##p2#define MY_NIL#define AB(p1,p2) MY_CAT(p1,p2)1,MY_CAT(A, B(x, y)) =>MY_CAT(x,y)2,MY_CAT(AB(x,y),MY_NIL) =>xy第2个不叫宏重入,叫“参数宏”,宏的参数是另外一个宏。这种情况下可以得到正确的展开结果xy。另外,这个地方为什么要定义MY_CAT_D?主要原因是MY_CAT在展开p1和p2的时候如果遇到##符号会停止展开,所以通过MY_CAT_D这个中间层可以使p1和p2先被展开然后再连接。
1在展开最外层MY_CAT之后,继续展开又会遇到MY_CAT,所以导致展开失败。
解决思路:通过定义相同功能不同名称的宏
方式1:定义AB的时候hardcode了一个可用的宏
#define MY_CAT1(p1,p2) MY_CAT1_D(p1,p2)#define MY_CAT1_D(p1,p2) p1##p2#define MY_CAT2(p1,p2) MY_CAT2_D(p1,p2)#define MY_CAT2_D(p1,p2) p1##p2#define MY_NIL#define AB(p1,p2) MY_CAT2(p1,p2)1,MY_CAT1(A, B(x, y)) =>xy
方式2:外层宏告诉内层宏使用相同功能可用的下一个“序号”
#define MY_CAT1(p1,p2) MY_CAT1_D(p1,p2)#define MY_CAT1_D(p1,p2) p1##p2#define MY_CAT2(p1,p2) MY_CAT2_D(p1,p2)#define MY_CAT2_D(p1,p2) p1##p2#define AB_D(d,p1,p2) MY_CAT##d(p1,p2)MY_CAT1(A, B_D(2,x, y)) => xy
方式3:外层宏可以自动探测下一个可用宏
step1:定义一系列的MY_CAT_xxx宏
#define MY_CAT_1(p1,p2) MY_CAT_1_D(p1,p2)#define MY_CAT_1_D(p1,p2) p1##p2#define MY_CAT_2(p1,p2) MY_CAT_2_D(p1,p2)#define MY_CAT_2_D(p1,p2) p1##p2#define MY_CAT_3(p1,p2) MY_CAT_3_D(p1,p2)#define MY_CAT_3_D(p1,p2) p1##p2#define MY_CAT_4(p1,p2) MY_CAT_4_D(p1,p2)#define MY_CAT_4_D(p1,p2) p1##p2#define MY_CAT_5(p1,p2) MY_CAT_5_D(p1,p2)#define MY_CAT_5_D(p1,p2) p1##p2#define MY_CAT_6(p1,p2) MY_CAT_6_D(p1,p2)#define MY_CAT_6_D(p1,p2) p1##p2#define MY_CAT_7(p1,p2) MY_CAT_7_D(p1,p2)#define MY_CAT_7_D(p1,p2) p1##p2#define MY_CAT_8(p1,p2) MY_CAT_8_D(p1,p2)#define MY_CAT_8_D(p1,p2) p1##p2
step2:定义谓词宏
#define MY_CAT_P(n) MY_CAT(MY_CAT_CHECK_, MY_CAT_ ## n(MY_NIL, MY_NIL))step3:根据谓词宏拼装的宏来定义结果宏
#define MY_CAT_CHECK_MY_NILMY_NIL 1#define MY_CAT_CHECK_MY_CAT_8(p1, p2) 0#define MY_CAT_CHECK_MY_CAT_7(p1, p2) 0#define MY_CAT_CHECK_MY_CAT_6(p1, p2) 0#define MY_CAT_CHECK_MY_CAT_5(p1, p2) 0#define MY_CAT_CHECK_MY_CAT_4(p1, p2) 0#define MY_CAT_CHECK_MY_CAT_3(p1, p2) 0#define MY_CAT_CHECK_MY_CAT_2(p1, p2) 0#define MY_CAT_CHECK_MY_CAT_1(p1, p2) 0
说明:举例,如果MY_CAT_xxx不可用(未定义或已经被外层使用),MY_CAT_P的返回结果是MY_CAT_CHECK_MY_CAT_xxx(MY_NILL,MY_NIL)。我们可以把这个系列都定义成0。如果MY_CAT_xxx可用,MY_CAT_P返回值是MY_CAT_CHECK_MY_NILMY_NIL,把它定义成1.
step4:定义探测宏参看宏元编程——技术——auto_rec
step5:测试
//#define AB MY_CAT(MY_CAT_, TL_AUTO_REC(MY_CAT_P, 4))#define AB TL_AUTO_REC(MY_CAT_P, 8)MY_CAT_4(A, B(x, y)) =>5(x,y)MY_CAT_2(A, B(x, y)) =>3(x,y)MY_CAT_1(A, B(x, y)) =>2(x,y)说明:这个地方故意把AB定义成TL_AUTO_REC(MY_CAT_P, 8),可以看到自动检测的可用的”序号“
0 0
- 宏元编程——技术——解决重入引起展开失败问题
- 宏元编程——技术——宏重载
- 宏元编程——技术——变参宏
- 宏元编程——技术——auto_rec
- 利用“宏元编程”解决重复问题
- Unix高级IO之多线程编程 ——可重入函数与不可重入函数
- 一个python程序员的ruby三日游(六)——重构(二)元编程
- 一个python程序员的ruby三日游(六)——重构(二)元编程
- 《Ruby 元编程》——十年来读到的最好的编程技术书籍
- 《Ruby 元编程》——十年来读到的最好的编程技术书籍
- 《Ruby 元编程》——十年来读到的最好的编程技术书籍
- 白话陈述之——从python脚本变化解析由路径引起的GP服务运行失败问题
- 宏元编程——代码生成
- 解决wordpress打不开——循环重定向问题
- WinExec可能会引起消息重入
- 算法爱好者——表达式展开 ? 待解决
- 访问 IIS 元数据库失败 , 通过aspnet_regiis解决不了,请查看一下是不是4.0引起的
- 亨元模式——池技术
- Android Studio中新建项目提示classes couldn't be instantiated解决方法
- 实现一个栈,要求Push(入栈),Pop(出栈),Min(返回最小值的操作)的时间复杂度为O(1)
- c++第1次实验-2
- android学习路线
- log4j经常使用到的两个日志文件log4j.properties和log4j.xml
- 宏元编程——技术——解决重入引起展开失败问题
- JSPatch实现原理详解
- 行人检测综述整理
- 基础总结篇之二:Activity的四种launchMode
- hbase的预分配region
- LVS的几种模式
- 动态规划之矩阵路径问题
- 智能智能(auto_ptr,unique_ptr,shared_ptr)(更新中。。。)
- phpmyadmin修改导sql文件大小上限