STL contains methods used to iterate elements in containers-iteration methods, including for_each, transform, copy, find, remove
1. Usage:
// Template function, print element <br/> template <class _ T> <br/> void print (_ t Arg) {<br/> cout <Arg <""; <br/>}< br/> // template function, returns the inverse of a given element. <br/> template <class _ T> <br/> _ t negative (_ t Arg) {<br/> return-(ARG ); <br/>}< br/> vector <int> days; <br/> for (INT I = 1; I <= 7; I ++) {<br/> days. push_back (I); <br/>}</P> <p> // print the elements in the container <br/> for_each (days. begin (), days. end (), print <int>); <br/> // reverse the elements in the container <br/> transform (days. begin (), days. end (), days. begin (), negative <int> );
2. Details
How to Implement for_each? Below is the source code of STL (excluding some diagnostic code)
// Template function for_each <br/> template <class _ init, <br/> class _ fn1> inline <br/> _ fn1 for_each (_ init _ first, _ init _ last, _ fn1 _ FUNC) <br/> {// Perform Function for each element <br/> for (; _ chkfirst! = _ Chklast; ++ _ chkfirst) <br/> _ FUNC (* _ chkfirst); <br/> return (_ FUNC); <br/>}
We can see that every element in the iteration container is used as a parameter to call the third parameter (function pointer, note that the function here is a global function)
3. Call class member functions, STL function Adapter
As shown in the for_each code, only global functions (ordinary functions) or function objects (function objects, refer to the description of function objects in STL) can be called, what should I do to call its member functions? Here, STL provides a design method: adapter (an adapter is a intermediary between two objects that cannot be directly communicated, which is also a pattern in the design ).
The adapters provided by STL include ptr_fun, mem_fun, and mem_fun_ref.
A) ptr_fun is a template function that returns a function object. The adapter can adapt to a common function (ordinary function). See the following STL code about ptr_fun:
// _ Arg is the parameter type of the function to be called, and _ result is the return value type of the function to be called. <Br/> // pointer_to_unary_function is a function object <br/> // The ptr_fun parameter is a function pointer and returns an instance of a pointer_to_unary_function object, this instance can be called by for_each <br/> template <class _ Arg, <br/> class _ result> inline <br/> pointer_to_unary_function <_ Arg, _ result, _ result (_ cdecl *) (_ Arg)> <br/> ptr_fun (_ result (_ cdecl * _ left) (_ Arg )) <br/> {// return pointer_to_unary_function functor adapter <br/> return (STD: pointer_to_unary_function <_ Arg, _ result, _ result (_ cdecl *) (_ Arg)> (_ left); <br/>}
Now let's take a look at the code of pointer_to_unary_function to know how the entire call process is implemented:
// This is a template class. It stores the function pointer passed in through the constructor and reloads the () operator. When calling, convert to a function pointer call <br/> // template class pointer_to_unary_function <br/> template <class _ Arg, <br/> class _ result, <br/> class _ fn = _ result (*) (_ Arg)> <br/> class pointer_to_unary_function <br/>: Public unary_function <_ Arg, _ result> <br/> {// functor adapter (* pfunc) (left) <br/> Public: <br/> explicit pointer_to_unary_function (_ FN _ left) <br/>: _ pfun (_ left) <br/>{// construct from pointer <br/>}</P> <p> _ result operator () (_ Arg _ left) const <br/> {// call function with operand <br/> return (_ pfun (_ left )); <br/>}</P> <p> protected: <br/> _ FN _ pfun; // The function pointer <br/> };
Note that the following code calls have the same effect:
For_each (days. begin (), days. end (), print <int>); <br/> for_each (days. begin (), days. end (), ptr_fun (print <int> ));
Ptr_fun provides adaptation for methods that require object functions, for example, the following code:
// Find first workingday <br/> bool isworkingday (INT day) {<br/> return day> = 1 & day <= 5; <br/>}</P> <p> // find the first workday <br/> vector <int>: iterator Pos = find_if (days. begin (), days. end (), isworkingday); </P> <p>/* <br/> Pos = find_if (days. begin (), days. end (), not1 (isworkingday )); </P> <p> // a compilation error occurs during this call. <br/> */</P> <p> // not1 is a function object, the constructor also needs a function object. The correct method is as follows: <br/> // find the first non-workday <br/> Pos = find_if (days. begin (), days. end (), not1 (ptr_fun (isworkingday )));
B) mem_fun. This adapter provides call to object member functions. Refer to the STL implementation code:
// Template class mem_fun_t, used to save class member function pointers and overload operators (). When calling (), the object's member functions are called (note the call method) <br/> // template class mem_fun_t <br/> template <class _ result, <br/> class _ ty> <br/> class mem_fun_t <br/>: public unary_function <_ ty *, _ result> <br/> {// functor adapter (* P-> * pfunc )(), non-const * pfunc <br/> Public: <br/> explicit mem_fun_t (_ result (_ TY: * _ PM) () <br/>: _ pmemfun (_ PM) <br/>{// construct from pointer <br/>}</P> <p> _ result operator () (_ ty * _ pleft) const <br/> {// call function <br/> return (_ pleft-> * _ pmemfun )()); <br/>}</P> <p> PRIVATE: <br/> _ result (_ TY: * _ pmemfun )(); // The member function pointer <br/>}; </P> <p> // template function mem_fun, returns a function object <br/> // template function mem_fun <br/> template <class _ result, <br/> class _ ty> inline <br/> mem_fun_t <_ result, _ ty> mem_fun (_ result (_ TY: * _ PM )()) <br/> {// return a mem_fun_t functor adapter <br/> return (STD: mem_fun_t <_ result, _ ty> (_ PM); <br/>}
C) mem_fun_ref, which has the same meaning as mem_fun. The difference is that mem_fun is called by Object Pointer and mem_fun_ref is called by object reference. refer to the following STL implementation code:
// Template class, overload (), call (), call the member function of the class for the specified object <br/> // template class mem_fun_ref_t <br/> template <class _ result, <br/> class _ ty> <br/> class mem_fun_ref_t <br/>: Public unary_function <_ ty, _ result> <br/> {// functor adapter (* left. * pfunc) (), non-const * pfunc <br/> Public: <br/> explicit mem_fun_ref_t (_ result (_ TY: * _ PM )()) <br/>: _ pmemfun (_ PM) <br/>{// construct from pointer <br/>}</P> <p> _ result operator () (_ ty & _ left) const <br/> {// call function <br/> return (_ left. * _ pmemfun) (); <br/>}</P> <p> PRIVATE: <br/> _ result (_ TY: * _ pmemfun )(); // The member function pointer <br/>}; </P> <p> // template function mem_fun_ref, returns a function object <br/> // template function mem_fun_ref <br/> template <class _ result, <br/> class _ ty> inline <br/> mem_fun_ref_t <_ result, _ ty> mem_fun_ref (_ result (_ TY: * _ PM )()) <br/> {// return a mem_fun_ref_t functor adapter <br/> return (STD: mem_fun_ref_t <_ result, _ ty> (_ PM); <br/>}
From mem_fun and mem_fun_ref, you can learn how to call the member methods of a specified class outside the object through object pointers and object references.
Note: mem_fun is used for pointer containers (supporting polymorphism) and mem_fun_ref is used for object containers.