posts - 18,  comments - 104,  trackbacks - 0

刚注册好cppblog的用户,这算是处女作了。 最近在学习boost::lambda, 分享下学习心得,共同进步。

当然这篇不是讲boost::lambda的用法的,如有有人感兴趣,可以参照:http://www.boost.org/doc/libs/1_38_0/doc/html/lambda.html

boost::lambda很复杂,一两句话也说不清楚,我尽力描述的简单一点,慢慢增加难度。

对我来说,boost::lambda省了不少事,我是喜欢stl algorithm的,现在基本上除非特殊情况,程序里面都不出现循环了。用for_each, transform 等等都可以搞定,否则,就要考虑数据结构和算法是不是有问题了。

但是问题在于每次用for_each的时候,都要定义一个仿函数(Modern C++ Design 这么叫的),麻烦,程序看起来也不怎么优雅顺畅,总要停下来去看那个仿函数到底干什么了,写的时候还要想是不是要泛化,很头痛。有了boost::lambda,就爽多了。看起来一目了然,写起来简单明了,不用关心类型。(是不是搞推销的?)

言归正传吧。

比如下面这段代码:

 1 vector<int> v;
 2 v.push_back(12);
 3 v.push_back(1342);
 4 v.push_back(23);
 5 
 6 struct OP
 7 {
 8     void operator()(int &i)
 9     {
10         i = 3;
11     }
12 };
13 
14 for_each(v.begin(), v.end(), OP());

够简单吧,把整个容器的值都改成3. 看到那个OP了吧,很简单的一件事情,非要让人写这么个struct,要是写成class,还要public,更郁闷。

看看用了boost::lambda以后的效果吧。
1 vector<int> v;
2 v.push_back(12);
3 v.push_back(1342);
4 v.push_back(23);
5 
6 for_each(v.begin(), v.end(), _1 = 3);
7 

比不用lambda整整少了一个OP定义呀,因为 string("OP()").length() == string("_1=3").length() .

那么,怎么才能达到这个效果呢,在这里,先假设我们只用int类型,关于泛化,下一篇再说,一次吃多了消化不良的。

熟悉for_each的都知道,for_each的第3个参数是个函数对象(我不用指针抱歉),注意区分仿函数和函数对象,仿函数是个类型,函数对象是个对象。

那么也就是说  _1 = 3 的结果应该是个函数对象,而且是个一元函数对象(不了解的去看for_each实现)。知道了这个,很容易写个大概:

 1 struct op
 2 {
 3     ??? operator()(int& i)
 4     {
 5         i = ???;
 6     }
 7 };
 8 
 9 struct place_holder
10 {
11     op operator=(int i)
12     {
13         return op???;
14     }
15 };
16 
17 place_holder _1;
18 
19 for_each(v.begin(), v.end(), _1 = 3);

???不是乱码,这里只是暂时不知道写什么。
我说过,这篇里面类型都是int,但是那个3怎么处理呢,明显要保存的仿函数里面去么,所以上面的代码进一步修改,
个OP里面增加变量,来保存3,函数返回值现在不重要,就写成int吧,以后有问题再说。
于是代码变成:

 1 struct op
 2 {
 3     op(int i)
 4         : _i(i)
 5     {}
 6 
 7     int _i;
 8 
 9     int operator()(int& i)
10     {
11         i = _i;
12     }
13 };
14 
15 struct place_holder
16 {
17     op operator=(int i)
18     {
19         return op(i)
20     }
21 };
22 
23 place_holder _1;
24 
25 for_each(v.begin(), v.end(), _1 = 3);

问题解决。

看到这里,整个程序已经可以执行了。把容器的值改成3,没问题吧。

整片文章都在一个假设之下,就是只用int,那要是不用int呢,情况就复杂一点了,下篇再讨论。 如果熟悉template的话,下篇很容易,否则,复习咯。
posted on 2009-02-19 19:19 尹东斐 阅读(1304) 评论(0)  编辑 收藏 引用 所属分类: 深入探索 boost::lambda 系列

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


<2009年3月>
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

常用链接

留言簿(4)

随笔档案

文章分类

文章档案

相册

好友博客

搜索

  •  

最新评论

阅读排行榜

评论排行榜