注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

天地不仁,以万物为Googol!

天行有常,不以物喜,不以己悲……

 
 
 

日志

 
 

lambda函数的实现  

2006-06-18 15:50:23|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
趁着晚上加班睡不着的时间,把boost::lambda的实现看了一下,确实精妙!
 
先说说啥是lambda函数。lambda函数就是用表达式组成的一个简单函数,比如:
_1+_2
 
上面的_1和_2代表第一个参数和第二个参数。整个式子代表的是一个函数(实际是个仿函数),而不是一个表达式。因此,可以这样写:
(_1+_2)(3,4)
 
这个式子返回3+4的值7。
 
这么写的好处是什么?在stl中,为了算法的独立性,经常会要求在调用算法时,传入一个函数,以实现一些独立于算法的功能。比如遍历一个容器:
for_each(v.begin(), v.end(), cout<<_1)
 
上面的for_each会遍历第一个参数和第二个参数之间(前闭后开)的所有元素,并以每个元素为参数,调用第三个参数传入的函数。这样,上面的那个式子的结果就是打印v容器中的所有元素的值。
 
lambda的介绍到此为止,现在开始讲讲lambda的实现。
 
初见lambda,确实觉得很诡异。在c++的标准语法下,cout<<_1与cout<<a竟然是完全不同的!前者返回一个仿函数,后者却是执行一个函数。跟到boost的源码,才发现_1是一个预先定义好的变量(具体类型忘了,懒得查了……)。但是为什么仅仅依靠这一个变量,就可以改变cout<<的行为呢?
 
改变行为?等等,c++有一个强大的特性,运算符重载,是可以改变语言的默认行为的。以此为线索,再次考察lambda源码,果然发现了以truple定义的,对运算法+、-、*、/、<<、>>等运算符的重载。也就说,cout<<_1实际被解释为operator<<(cout, _1),之后由于_1的存在,使得operator<<定位到lambda源码中重载的operator<<,而这个重载的operator<<并没有按照通常的<<规范,返回一个ostream,而是返回了一个仿函数(具体类型还是被遗忘的对象……)。这样,就完成了仅仅通过一个表达式,来定义一个函数的功能,真是不可思议!
 
很可惜,c++不允许重载三目运算符?:,也因此,不可能写这样的lambda表达式:
(_1)?_2:_3
 
这样,lambda表达式将只有顺序执行的能力,而没有选择或者循环的能力。同时,对于已经存在的变量a和b,不知道如下lambda表达式是否合法,有待验证:
a+b+_1
 
尽管如此,lambda表达式还是非常有用的,毕竟传给算法的函数一般都很小,只用完成某个特殊的功能就可以。
 
lambda函数实现里面最精妙的地方:不按规范重载运算符。大师突破规范,便是神迹……
 
ps,c++ committee看到了lambda的实现,不知道会不会开放对?:的重载限制
  评论这张
 
阅读(659)| 评论(3)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017