概述
参考地址
C/C++宏编程的艺术
用括号对封装参数叫元组
,展开时移除.
#define 宏删括(T) 宏删括_ T
#define 宏删括_(...) __VA_ARGS__
用宏函数
来代替特殊符号
,这是懒求值
(即尽量先展开再求值).
#define 宏逗() ,
#define 宏左括() (
#define 宏右括() )
#define 宏空的()
先展开,再求值:
#define 宏连(A,B) 宏连_(A,B)
#define 宏连_(A,B) A##B
不然,要出问题.自增/自减
逻辑运算,都很简单.
懒求值很爽,不犯错误:
#define 宏如(判,则,异) 宏连(宏如_,宏极(判))(则,异)
#define 宏逗如(N) 宏如(N,宏逗,宏空的)()
//都是一样的.
相当于()()
这种二次函数
了.
#define 包围(N)
宏如(N,宏左括,[ 宏空的)() N 宏如(N,宏右括,] 宏空的)()
都是尽量懒求值
,先展开再求值
.
c++20
用__VA_OPT__
来处理变长参数展开为空
的情况.如__VA_OPT__(,) __VA_ARGS__)
表示为空时,则不要这个,
号.
#define 福(P,T) 宏如(P,宏几_1,宏几_0) T
福(0,(foo,bar)) // -> foo
福(1,(foo,bar)) // -> bar
福(0,(baz)) // -> baz
同样的懒求值
,由于是T是元组
所以可以直接连接
.
然后是检查变长参数是否为空
.
#define 宏是空(...)
宏与(宏与(宏非(宏有逗(__VA_ARGS__)),宏非(宏有逗(__VA_ARGS__()))),宏与(宏非(宏有逗(宏逗值 __VA_ARGS__)),宏有逗(宏逗值 __VA_ARGS__())))
#define 宏有逗(...) 宏几_8(__VA_ARGS__,1,1,1,1,1,1,1,0,0)
#define 宏逗值(...) ,
这里要逗 变参()
展开为逗,而变参,变参(),逗 变参
均展开为非逗
才叫宏是空的
.
#define 宏变选逗(...) 宏微软(宏逗如(宏非(宏是空(__VA_ARGS__))))
实现c++20
的(,)
,然后就可实现参数个数
:
#define 宏参数(...)
宏微软(宏几(8,__VA_ARGS__ 宏变选逗(__VA_ARGS__) 8,7,6,5,4,3,2,1,0))
即变参
后面跟着个动态变化
的,
号.只能用宏几(8
,不能用宏几8
.后者未展开.前者会展开
.与微软__VA_ARGS__
一样的道理.
然后实现每一
,这是重点
:
#define 宏每一(干,c,...)
宏微软(宏连(宏每一_,宏参数(__VA_ARGS__))(干,c,__VA_ARGS__))
#define 宏每一_1(干,c,v,...) 干(c,v)
#define 宏每一_2(干,c,v,...)
干(c,v) 宏微软(宏每一_1(干,c,__VA_ARGS__))
...
这里与原文不一样,人家的有i
参数,我这里去掉了.随时都要注意.有__VA_ARGS__
,就记得加上宏微软
的扩展.不然不行的.
BOOST_PP
提供四种数据结构:元组,序列,列表,数组
.
结构 | 造型 |
---|---|
元组 | 都放一个括号里面 |
序列 | 每个元素放一括号 |
列表 | 递归二元组,类似c++ 的型列 (大神的现代c++设计 ). |
数组 | (长度,元组),已过时. |
宏
在遇见当前宏
是,不会继续展开.因而不支持递归/重入
.二维的,比较麻烦.要自己去学习.
宏当.
#define 宏当 宏当_1
#define 宏当_1(判,操作,值)
宏如(判(值),宏当_2,值 宏空值) (判,操作,宏如(判(值),操作,宏空值)(值))
...
判
为判断
,可接参数
.操作,接收操作
,返回下个状态
.第3个为状态
.有简单的,有复杂的.如:
#define 宏当(f,o,s) 宏当_1(f,o,s)
#define 宏当_1(f,o,s) 宏如(f(1,s),宏当_2(f,o,o(1,s)),s)
#define 宏当_2(f,o,s) 宏如(f(2,s),宏当_3(f,o,o(2,s)),s)
...
及类似,f/o
接2个参数
.
#define 宏当 宏当_1
#define 宏当_1(判,操作,值)
宏如(判(值),宏当_2,值 宏空值) (判,操作,宏如(判(值),操作,宏空值)(值))
...
#define 判(值) 宏取几(1,值)
#define 操作(值)
(宏取几(0,值) + 宏取几(1,值),宏降(宏取几(1,值)))
上面的,判断/操作
接1
个参数.即宏当
有多种形式.
还有不带状态的自动推导
.不过建议宏当
尽量传递状态
,这样可以不用自动推导
.
借助宏当
,可以实现+-*/%
,甚至比较
操作.宏编程
主要是在非用宏不可的地方
,比如定义类
.而其他很多都可借用编译时元编程
,那里就可以大展伸手
了.
宏毕竟还是带链子
跳舞.会宏每一
,最多宏当
就行啦.
最后
以上就是活力绿茶为你收集整理的学习宏编程C/C++宏编程的艺术的全部内容,希望文章能够帮你解决学习宏编程C/C++宏编程的艺术所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复