剛注冊好cppblog的用戶,這算是處女作了。 最近在學(xué)習(xí)boost::lambda, 分享下學(xué)習(xí)心得,共同進(jìn)步。
當(dāng)然這篇不是講boost::lambda的用法的,如有有人感興趣,可以參照:http://www.boost.org/doc/libs/1_38_0/doc/html/lambda.html
boost::lambda很復(fù)雜,一兩句話也說不清楚,我盡力描述的簡單一點,慢慢增加難度。
對我來說,boost::lambda省了不少事,我是喜歡stl algorithm的,現(xiàn)在基本上除非特殊情況,程序里面都不出現(xiàn)循環(huán)了。用for_each, transform 等等都可以搞定,否則,就要考慮數(shù)據(jù)結(jié)構(gòu)和算法是不是有問題了。
但是問題在于每次用for_each的時候,都要定義一個仿函數(shù)(Modern C++ Design 這么叫的),麻煩,程序看起來也不怎么優(yōu)雅順暢,總要停下來去看那個仿函數(shù)到底干什么了,寫的時候還要想是不是要泛化,很頭痛。有了boost::lambda,就爽多了。看起來一目了然,寫起來簡單明了,不用關(guān)心類型。(是不是搞推銷的?)
言歸正傳吧。
比如下面這段代碼:
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());
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
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() .
那么,怎么才能達(dá)到這個效果呢,在這里,先假設(shè)我們只用int類型,關(guān)于泛化,下一篇再說,一次吃多了消化不良的。
熟悉for_each的都知道,for_each的第3個參數(shù)是個函數(shù)對象(我不用指針抱歉),注意區(qū)分仿函數(shù)和函數(shù)對象,仿函數(shù)是個類型,函數(shù)對象是個對象。
那么也就是說 _1 = 3 的結(jié)果應(yīng)該是個函數(shù)對象,而且是個一元函數(shù)對象(不了解的去看for_each實現(xiàn))。知道了這個,很容易寫個大概:
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);
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怎么處理呢,明顯要保存的仿函數(shù)里面去么,所以上面的代碼進(jìn)一步修改,
個OP里面增加變量,來保存3,函數(shù)返回值現(xiàn)在不重要,就寫成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);
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);
問題解決。
看到這里,整個程序已經(jīng)可以執(zhí)行了。把容器的值改成3,沒問題吧。
整片文章都在一個假設(shè)之下,就是只用int,那要是不用int呢,情況就復(fù)雜一點了,下篇再討論。 如果熟悉template的話,下篇很容易,否則,復(fù)習(xí)咯。