(原創) 如何使for_each()傳回值? (C/C++) (STL)
Abstract
for_each()是STL中少數可以回傳值的algorithm,此範例在展示for_each()此特殊功能與function object可以留住state的特性。
Introduction
function object與global function的差別除了function object可以傳入參數外,還可以不使用static就可以留住state。
一個簡單的需求,想要每印n個數字就換行,並且統計出所有iterator的和,所以function object必須能留住state才知道目前印了幾個數字,且統計sum為多少。
Sample Code
1/*
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3
4Filename : GenericAlgo_for_each_state_returnValue.cpp
5Compiler : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
6Description : Demo how to use for_each to return value and remain state.
7Release : 05/13/2007 1.0
8 05/15/2007 2.0
9*/
10
11#include <iostream>
12#include <algorithm>
13#include <vector>
14
15using namespace std;
16
17class printElem {
18private:
19 int _n;
20 int _cnt;
21 int _sum;
22
23public:
24 printElem(int n = 5) : _n(n), _cnt(0), _sum(0) {}
25
26 void operator() (int elem) {
27 ++_cnt;
28 _sum += elem;
29
30 cout << elem;
31
32 (_cnt % _n) ? cout << " " : cout << endl;
33 }
34
35 operator int() {
36 return _sum;
37 }
38};
39
40int main() {
41 vector<int> ivec;
42
43 for(int i = 0; i != 20; ++i)
44 ivec.push_back(i);
45
46 int sum = for_each(ivec.begin(), ivec.end(), printElem(5));
47
48 cout << "sum is " << sum << endl;
49}
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3
4Filename : GenericAlgo_for_each_state_returnValue.cpp
5Compiler : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
6Description : Demo how to use for_each to return value and remain state.
7Release : 05/13/2007 1.0
8 05/15/2007 2.0
9*/
10
11#include <iostream>
12#include <algorithm>
13#include <vector>
14
15using namespace std;
16
17class printElem {
18private:
19 int _n;
20 int _cnt;
21 int _sum;
22
23public:
24 printElem(int n = 5) : _n(n), _cnt(0), _sum(0) {}
25
26 void operator() (int elem) {
27 ++_cnt;
28 _sum += elem;
29
30 cout << elem;
31
32 (_cnt % _n) ? cout << " " : cout << endl;
33 }
34
35 operator int() {
36 return _sum;
37 }
38};
39
40int main() {
41 vector<int> ivec;
42
43 for(int i = 0; i != 20; ++i)
44 ivec.push_back(i);
45
46 int sum = for_each(ivec.begin(), ivec.end(), printElem(5));
47
48 cout << "sum is " << sum << endl;
49}
執行結果
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
sum is 190
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
sum is 190
17行
private:
int _n;
int _cnt;
int _sum;
int _n;
int _cnt;
int _sum;
_n為設定幾個字跳行
_cnt統計目前已經印了幾個字
_sum統計目前加總結果
29行
if (_cnt % _n)
cout << elem << " ";
else
cout << elem << endl;
cout << elem << " ";
else
cout << elem << endl;
若每印n個字,就加印換行
35行
operator int() {
return _sum;
}
return _sum;
}
為了讓for_each()能傳回值,特別改寫operator int(),讓function object能夠傳回值。
46行
int sum = for_each(ivec.begin(), ivec.end(), printElem(5));
這樣for_each()就能風風光光的每n個字就換行,還可以順便加總結果。
Conclusion
STL真的很神奇,以上的程式想一行一行翻成C#還真的做不到呢!!
See Also
(原創) 如何正確的使用迴圈(使用for_each)? (C/C++) (STL) (template)
Reference
Nicolai M. Josuttis,The C++ Standard Library : A Tutorial and Referencd,Addison Wesley,1999