janvy

posts - 12, comments - 1, trackbacks - 0, articles - 0

Abstract

Motivation

Introduction

#include <vector>
#include <iostream>

using namespace std;

int main() {
int ia[] = {1, 2, 3};
vector<int> ivec(ia, ia + sizeof(ia) / sizeof(int));

for(vector<int>::const_iterator iter = ivec.begin(); iter != ivec.end(); ++iter) {
cout << *iter << endl;
}
}

1
2
3

for(vector<int>::const_iterator iter = ivec.begin(); iter != ivec.end(); ++iter) {

for_each()事實上是個function template，其實做如下[effective STL item 41]

template<typename InputIterator, typename Function>
Function for_each(InputIterator beg, InputIterator end, Function f) {
while(beg != end)
f(*beg++);
}

Procedure Based與for_each()搭配
1.不傳入參數

1/**//*
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3Filename    : GenericAlgo_for_each_GlobalFunction.cpp
4Compiler    : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
5Description : Demo how to use for_each with global function
6Release     : 05/11/2007 1.0
7*/
8#include <iostream>
9#include <vector>
10#include <iostream>
11#include <algorithm>
12
13using namespace std;
14
15void printElem(int& elem) {
16  cout << elem << endl;
17}
18
19int main() {
20  int ia[] = {1, 2, 3};
21  vector<int> ivec(ia, ia + sizeof(ia) / sizeof(int));
22
23  for_each(ivec.begin(), ivec.end(), printElem);
24}

1
2
3

23行

for_each(ivec.begin(), ivec.end(), printElem);

2.傳入參數

1/**//*
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3Filename    : GenericAlgo_for_each_GlobalFunctionWithParameter.cpp
4Compiler    : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
5Description : Demo how to use for_each with global function with Parameter
6Release     : 05/11/2007 1.0
7*/
8#include <iostream>
9#include <vector>
10#include <iostream>
11#include <algorithm>
12#include <functional>
13
14using namespace std;
15
16void printElem(int elem, const char* prefix) {
17  cout << prefix << elem << endl;
18}
19
20int main() {
21  int ia[] = {1, 2, 3};
22  vector<int> ivec(ia, ia + sizeof(ia) / sizeof(int));
23
24  for_each(ivec.begin(), ivec.end(), bind2nd(ptr_fun(printElem), "Element:"));
25}

Element:1
Element:2
Element:3

Object Oriented與for_each()搭配
1.不傳入參數

1/**//*
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3Filename    : GenericAlgo_for_each_FunctionObject.cpp
4Compiler    : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
5Description : Demo how to use for_each with function object
6Release     : 05/11/2007 1.0
7*/
8#include <iostream>
9#include <vector>
10#include <iostream>
11#include <algorithm>
12
13using namespace std;
14
15struct printElem {
16  void operator() (int elem) {
17    cout << elem << endl;
18  }
19};
20
21int main() {
22  int ia[] = {1, 2, 3};
23  vector<int> ivec(ia, ia + sizeof(ia) / sizeof(int));
24
25  for_each(ivec.begin(), ivec.end(), printElem());
26}

1
2
3

2.傳入參數

1/**//*
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3Filename    : GenericAlgo_for_each_FunctionObjectWithParameter.cpp
4Compiler    : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
5Description : Demo how to use for_each with function object with parameter
6Release     : 05/11/2007 1.0
7*/
8#include <iostream>
9#include <vector>
10#include <iostream>
11#include <algorithm>
12
13using namespace std;
14
15struct printElem {
16  const char* _prefix;
17
18  printElem(const char* prefix) : _prefix(prefix) {}
19
20  void operator() (int elem) {
21    cout << _prefix << elem << endl;
22  }
23};
24
25int main() {
26  int ia[] = {1, 2, 3};
27  vector<int> ivec(ia, ia + sizeof(ia) / sizeof(int));
28
29  for_each(ivec.begin(), ivec.end(), printElem("Element:"));
30}

Element:1
Element:2
Element:3

function object有很多種寫法，但只要是function object都可以跟for_each()合作。

3.member_function與for_each()搭配
3.1 不傳入參數

for_each(_doorVec.begin(), _doorVec.end(),&Door::open);

for_each(_doorVec.begin(), _doorVec.end(), mem_fun_ref(&Door::open));

1/**//*
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3
4Filename    : GenericAlgo_for_each_MemberFunctionObject.cpp
5Compiler    : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
6Description : Demo how to use for_each with member function with object
7Release     : 05/11/2007 1.0
8*/
9#include <vector>
10#include <iostream>
11#include <algorithm>
12#include <functional>
13
14using namespace std;
15
16class Door {
17public:
18  void open() const {
19    cout << "open door horizontally" << endl;
20  }
21
22  void close() const {
23    cout << "close door horizontally" << endl;
24  }
25};
26
27class DoorController {
28protected:
29  vector<Door> _doorVec;
30
31public:
34  }
35
36  void openDoor() const {
37    for_each(_doorVec.begin(), _doorVec.end(), mem_fun_ref(&Door::open));
38  }
39};
40
41int main() {
42  DoorController dc;
45  dc.openDoor();
46}

open door horizontally
open door horizontally

37行

for_each(_doorVec.begin(), _doorVec.end(), mem_fun_ref(&Door::open));

1/**//*
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3
4Filename    : GenericAlgo_for_each_MemberFunctionObjectPointer.cpp
5Compiler    : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
6Description : Demo how to use for_each with member function with object pointer
7Release     : 05/11/2007 1.0
8*/
9#include <vector>
10#include <iostream>
11#include <algorithm>
12#include <functional>
13
14using namespace std;
15
16class AbstractDoor {
17public:
18  virtual void open() const {
19    cout << "open door horizontally" << endl;
20  }
21
22  virtual void close() const {
23    cout << "close door horizontally" << endl;
24  }
25};
26
27class HorizontalDoor : public AbstractDoor {
28};
29
30class VerticalDoor : public AbstractDoor {
31public:
32  void open() const {
33    cout << "open door vertically" << endl;
34  }
35
36  void close() const {
37    cout << "close door vertically" << endl;
38  }
39};
40
41class DoorController {
42protected:
43  vector<AbstractDoor*> _doorVec;
44
45public:
48  }
49
50  void openDoor() const {
51    for_each(_doorVec.begin(), _doorVec.end(), mem_fun(&AbstractDoor::open));
52  }
53};
54
55int main() {
56  DoorController dc;
59  dc.openDoor();
60}

open door horizontally
open door vertically

51行

for_each(_doorVec.begin(), _doorVec.end(), mem_fun(&AbstractDoor::open));

3.2傳入參數

1/**//*
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3
4Filename    : GenericAlgo_for_each_MemberFunctionObjectPointerWithParameter.cpp
5Compiler    : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
6Description : Demo how to use for_each with member function with object pointer
7Release     : 05/11/2007 1.0
8*/
9#include <iostream>
10#include <vector>
11#include <algorithm>
12#include <functional>
13
14using namespace std;
15
16class AbstractDoor {
17public:
18  virtual void open() const {
19    cout << "open door horizontally" << endl;
20  }
21
22  virtual void close() const {
23    cout << "close door horizontally" << endl;
24  }
25
26  virtual void openDoorBy(const char* name) const {
27    cout << name << " ";
28    open();
29  }
30};
31
32class HorizontalDoor : public AbstractDoor {
33};
34
35class VerticalDoor : public AbstractDoor {
36public:
37  void open() const {
38    cout << "open door vertically" << endl;
39  }
40
41  void close() const {
42    cout << "close door vertically" << endl;
43  }
44};
45
46class DoorController {
47protected:
48  vector<AbstractDoor*> _doorVec;
49
50public:
53  }
54
55  void openDoor() const {
56    for_each(_doorVec.begin(), _doorVec.end(), bind2nd(mem_fun(&AbstractDoor::openDoorBy), "John"));
57  }
58};
59
60int main() {
61  DoorController dc;
64  dc.openDoor();
65}

1John open door horizontally
2John open door vertically

56行

for_each(_doorVec.begin(), _doorVec.end(), bind2nd(mem_fun(&AbstractDoor::openDoorBy), "John"));

Generics與for_each()搭配
1.Function Template
1.1不傳入參數

1/**//*
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3Filename    : GenericAlgo_for_each_FunctionTemplate.cpp
4Compiler    : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
5Description : Demo how to use for_each with function template
6Release     : 05/11/2007 1.0
7*/
8#include <iostream>
9#include <vector>
10#include <iostream>
11#include <algorithm>
12
13using namespace std;
14
15template<typename T>
16void printElem(T elem) {
17  cout << elem << endl;
18}
19
20int main() {
21  int ia[] = {1, 2, 3};
22  vector<int> ivec(ia, ia + sizeof(ia) / sizeof(int));
23
24  for_each(ivec.begin(), ivec.end(), printElem<int>);
25  //for_each(ivec.begin(), ivec.end(), (void(*)(int))printElem);
26}

1
2
3

for_each(ivec.begin(), ivec.end(), printElem<int>);

for_each(ivec.begin(), ivec.end(), (void(*)(int))printElem);

template function並沒有確定型別，但轉成function pointer時，並須明確轉成int型別的function pointer。

1.2 傳入參數

1.int或enum
2.pointer：pointer to object，pointer to function，pointer to member。
3.reference：reference to object，reference to function。

1/**//*
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3Filename    : GenericAlgo_for_each_FunctionTemplateWithNontypeParameter.cpp
4Compiler    : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
5Description : Demo how to use for_each with function template with nontype parameter
6Release     : 05/11/2007 1.0
7*/
8#include <iostream>
9#include <vector>
10#include <iostream>
11#include <algorithm>
12
13using namespace std;
14
15template<typename T, int i>
16void printElem(T elem) {
17  cout << i << ":"  << elem << endl;
18}
19
20int main() {
21  int ia[] = {1, 2, 3};
22  vector<int> ivec(ia, ia + sizeof(ia) / sizeof(int));
23
24  for_each(ivec.begin(), ivec.end(), printElem<int, 5>);
25}

5:1
5:2
5:3

2.Class Template
2.1 不傳入參數

1/**//*
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3Filename    : GenericAlgo_for_each_ClassTemplate.cpp
4Compiler    : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
5Description : Demo how to use for_each with class template
6Release     : 05/11/2007 1.0
7*/
8#include <iostream>
9#include <vector>
10#include <iostream>
11#include <algorithm>
12#include <functional>
13
14using namespace std;
15
16template<typename T>
17class printElem : public unary_function<T, void> {
18public:
19  void operator() (T elem) {
20    cout << elem << endl;
21  }
22};
23
24int main() {
25  int ia[] = {1, 2, 3};
26  vector<int> ivec(ia, ia + sizeof(ia) / sizeof(int));
27
28  for_each(ivec.begin(), ivec.end(), printElem<int>());
29}

1
2
3

17行

class printElem : public unary_function<T, void> {

template <class InputIterator, class UnaryFunction>
UnaryFunction for_each(InputIterator first, InputIterator last, UnaryFunction f);

2.2 傳入參數

1/**//*
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3Filename    : GenericAlgo_for_each_ClassTemplateWithParameter.cpp
4Compiler    : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
5Description : Demo how to use for_each with class template & parameter
6Release     : 05/11/2007 1.0
7*/
8#include <iostream>
9#include <vector>
10#include <iostream>
11#include <algorithm>
12#include <functional>
13
14using namespace std;
15
16template<typename T, typename U>
17class printElem : public unary_function<T, void> {
18private:
19  U _prefix;
20
21public:
22  printElem(U prefix) : _prefix(prefix) {}
23
24  void operator() (T elem) {
25    cout << _prefix << elem << endl;
26  }
27};
28
29int main() {
30  int ia[] = {1, 2, 3};
31  vector<int> ivec(ia, ia + sizeof(ia) / sizeof(int));
32
33  for_each(ivec.begin(), ivec.end(), printElem<int, const char*>("Element:"));
34}

Element:1
Element:2
Element:3

Conclusion