宏的语法局限

1 篇文章 0 订阅

宏是非常强大好用的工具。

基本上跨平台的类库,都是密密麻麻的宏。同时宏也常用于自动生成代码。

 

 

 

不过宏的语法有一定的局限性。

先从简单的宏看起:

从语法上来看,就是做个映射:

tag -> *

tag(x) -> *x*

 

但是我们做不到映射tag的一部分:

例如: 

// MyCoutHelloWorld  -> 错误 

 

另外,tag的字符集合是[字母数字-_]

这里推导出:任何含有“.”的代码段都至少含有两个tag,并且tag之间无法感知。

这会导致一些困难,举个常见的例子:

log类通常要打出行号(类似的,通常也要打出文件名),行号是一个预定义的宏:__LINE__

我们希望保持代码简洁,也就是说期望打log的时候,不用传递行号(文件名)。例如:

注意到chatlog.info中间有一个点,根据前面的推论,这肯定是两个tag,并且不能相互感知。

 

1. 最简单的办法自然是映射info这个tag,如

但是这么做不大好,因为info这个tag太常见了,很容易就和别人的代码冲突了。 

2. 另一种办法是定义一个不常见的tag,如myInfo(或者info__),这样代码就变成

这样也不太好,因为1. myInfo不存在于logger类里,这会让人很困惑;2. myInfo这个名字不自然,怪怪的。 

3.  看来对info这个tag不能做映射。

来看看chatlog这个tag。这个tag通常是被定制的,既然是被定制的,就意味着进行映射是不会有冲突问题的。

这个tag可以得到__LINE__这些变量(也可以得到__FILE__等)。问题是需要把这些变量传递给info这个tag。

不管形式看起来怎么样,每个tag最后的值都是一个对象(或者变量)。info的值只能是函数,chatlog最后的值一定是一个logger对象(因为info是logger里的函数,也因为有‘.’号)。

问题转换成:如何把一个对象obj1知道的变量在fun1函数传给fun2函数?很简单,先把变量存起来,然后在fun1函数里,调用fun2函数。

最直接的做法,就是把__LINE__这些变量保存到logger对象里。

可以这么做:

看起来效果还不错,性能也可以接受。

不过还有改进的余地,明显strFilePath和strLine不应该属于logger类的。

既然不属于logger类,chatlog最后的值又必须是logger类,那么就放到一个logger的wrapper类里吧。。。

可以这么做:

当然还能再改进,懒得写了。

 

 那一天要能支持正则表示的宏,那就太完美了。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值