Analysis of iterative functions in STL

Source: Internet
Author: User

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.

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.