# Include <iostream> # include <algorithm> using namespace STD; // callback function void call_back (char ELEM) {cout <ELEM <Endl ;} // simulation function struct functor {void operator () (char ELEM) {cout <ELEM <Endl ;}; int main () {string stra = "hello "; string strb = "world"; for_each (stra. begin (), stra. end (), functor ()); cout <"============= gap ===============" <Endl; for_each (strb. begin (), strb. end (), call_back); getchar (); Return 0 ;}
H
E
L
L
O
============= Gap ========================
W
O
R
L
D
What are the differences between the two?
What if I want for_each to traverse a vector of the int type instead of a string?
Is it necessary to rewrite a callback function of the int type as a parameter? If there are N types of container traversal, isn't it necessary to write n callback functions or N imitation function classes?
Neither !!!
C ++ class templates and function templates can also be used for callback.
? # Include <iostream> # include <algorithm> # include <vector> using namespace STD; // template function template <typename T> void call_back (t elem) {cout <ELEM <Endl;} // The Imitation function template <typename T> class functor {public: functor (): m_val (0) {cout <"functor () "<Endl ;}~ Functor () {cout <"~ Functor () "<Endl;} void operator () (t elem) {do (ELEM);} // Void Do (t elem) {m_val + = ELEM; cout <ELEM <"/" <m_val <Endl;} PRIVATE: T m_val;}; int main () {vector <int> VEC; Vec. push_back (1); Vec. push_back (2); Vec. push_back (3); Vec. push_back (4); Vec. push_back (5); for_each (VEC. begin (), VEC. end (), call_back <int> ); cout <"============= gap ===============" <Endl; for_each (VEC. begin (), VEC. end (), functor <int> (); Return 0 ;}
1
2
3
4
5
============= Gap ========================
Functor ()
1/1
2/3
3/6
4/10
5/15
~ Functor ()
~ Functor ()
~ Functor ()
Reasons for the three-step structure:
First, attach the for_each source code (vc2008)
template<class _InIt,class _Fn1>inline _Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func){ // perform function for each element _DEBUG_RANGE(_First, _Last); _DEBUG_POINTER(_Func); _CHECKED_BASE_TYPE(_InIt) _ChkFirst(_CHECKED_BASE(_First)); _CHECKED_BASE_TYPE(_InIt) _ChkLast(_CHECKED_BASE(_Last)); for (; _ChkFirst != _ChkLast; ++_ChkFirst) _Func(*_ChkFirst); return (_Func);}
Functor <int> () generates a temporary object for parameter passing (value) construction. The for_each parameter value is parsed, and the copy construction is performed once) for_each returns the object (value) of the imitation function, which is copied and constructed once, because there is no duplicate copy constructor, the normal constructor used to create a temporary object for the first time is printed. In fact, three constructor objects are generated in this process.
If you change the code:
# Include <iostream> # include <algorithm> # include <vector> using namespace STD; Template <typename T> class functor {public: functor (): m_val (0) {cout <"functor ()" <This <Endl;} functor (functor & that) {This-> m_val = That. m_val; cout <"Copy functor ()" <This <Endl ;}~ Functor () {cout <"~ Functor () "<This <Endl;} void operator () (t elem) {do (ELEM);} // cite the chestnut Void Do (t elem) {m_val + = ELEM; cout <ELEM <"/" <m_val <Endl;} t getval () {return m_val;} PRIVATE: T m_val ;}; int main () {vector <int> VEC; Vec. push_back (1); Vec. push_back (2); Vec. push_back (3); Vec. push_back (4); Vec. push_back (5); functor <int> func; functor <int> & ref = for_each (VEC. begin (), VEC. end (), func); cout <ref. getval () <Endl; return 0 ;}
Running result
Functor () 0032f800 // real parameter imitation function object in Main Function
Copy functor () 0032f68c // The parameter object is copied to [real object] to create a parameter object.
1/1
2/3
3/6
4/10
5/15
Copy functor () 0032f7e8 // returns the value type of the object to copy the structure of the [parameter object]
~ Functor () 0032f68c // Analysis configuration parameter object
15
~ Functor () 0032f7e8 // destructor Return Value Object
~ Functor () 0032f800 // destructor real parameter object
It's clear now!
I personally think that using the callback function is efficient. From the above example, we can see that it is costly to construct one copy and construct two analyses and three analyses.
Finally, return to the imitation and callback functions.
The difference is:
Using the imitation function, you can declare to narrow the scope of the business-related classes.
You can use the member attributes and member functions of the class by using the imitation function.
The Imitation function isClassVarious object-oriented mechanisms can be used to encapsulate inheritance polymorphism)
If a callback function is used, it can only be declared as a static member function or a global function of a class. To use resources within the class, you must use some means to transmit parameters without directly using the member function.