Start with for_each and start with callback and imitation functions.

Source: Internet
Author: User
# 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:

  1. Using the imitation function, you can declare to narrow the scope of the business-related classes.

  2. You can use the member attributes and member functions of the class by using the imitation function.

  3. The Imitation function isClassVarious object-oriented mechanisms can be used to encapsulate inheritance polymorphism)

  4. 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.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.