[STL] function object/function imitation

Source: Internet
Author: User
Tags print print
When it comes to C ++ STL, we first think of three major components: Containers, iterators, algorithms, containers, iterators, and algorithms. Containers provide users with common data structures. Most of the algorithms are basic algorithms that are independent from the container. The iterator is an interface provided by the container, and the algorithm uses the iterator to manipulate the container. Next we will introduce another component, function object (function object, jjhou translated as functor imitation function ).

What is a function object?

As the name implies, a function object is first an object, that is, an instance of a class. Second, the behavior of the function object is the same as that of the function, that is, you can use the function object (# Add Class Object) like calling the function, such as passing parameters and returning values. This behavior is implemented through the () operator of the overload class. For example,

Class print <br/>{< br/> Public: <br/> void operator () (int n) <br/>{< br/> STD :: cout <n <STD: Endl; <br/> return; <br/>}< br/> }; <br/> int <br/> main (INT argc, char ** argv) <br/>{< br/> Print print; <br/> Print (372 ); <br/> Print. operator () (372 );//~ Explicit call <br/> return 0; <br/>}< br/>

In fact, we have been using function objects for a long time. When you write sort (v. begin (), V. end () (assume that V is a vector <int>). In fact, sort (v. begin (), V. end (), less <int> (), so that sort will sort V from small to large. To reverse sort, you need to explicitly specify a sorting rule for sort, that is, the function object greater <int> (). less <t> and greater <t> are two template classes in STL. They use the <and> operators of the T type. A typical Implementation of less <t> may be as follows:

Template <class T> <br/> class Less <br/> {<br/> Public: <br/> bool operator () (const T & L, const T & R) const <br/>{< br/> return l <r; <br/>}< br/>}; <br/>Function Object Classification

Function objects in STL are generally divided into the following types based on purpose and parameter features: predicates, arithmetic function objects, binders, negaters, member function adapters, and pointer to function adapters. Next, we will introduce two base classes first:

Template <class Arg, class res> <br/> struct unary_function //~ Basic class of one-dimensional function object <br/>{< br/> typedef Arg argument_type; <br/> typedef res result_type; <br/> }; </P> <p> template <class arg1, class arg2, class res> <br/> struct binary_function //~ Binary Function object base class <br/>{< br/> typedef arg1 first_argument_type; <br/> typedef arg2 second_argument_type; <br/> typedef res result_type; <br/> }; <br/>

To use these two base classes, you must first include the header file.

Predicates

Predicate is a function object. The return value (which should be the return value of operator () is a boolean type and one or two parameters are accepted. It is usually used to determine the validity of an object (when a parameter is used) or compare two objects (such as less ). You can define your own predicate as needed, but STL already defines some predicate, which you can use directly.

Predicates
Predicate Type Description
Performance_to () Binary Usage = judgment
Not_0000_to () Binary Use! = Judgment
Less () Binary Use <
Greater () Binary Use>
Less_equal () Binary Use <=
Greater_equal () Binary Use> =
Logical_not () Unary Use! Logical Inversion
Logical_and () Binary Usage & logic and
Logical_or () Binary Use | logical or
Arithmetic Operation function object

For simple arithmetic operations, this type of function objects are rarely used and usually defined by myself.

Arithmetic Operation function object
Function object Type Description
Negate () Unary Use-negative
Plus () Binary Use + addition
Minus () Binary Use-Subtraction
Multiplies () Binary Use * Multiplication
Divides () Binary Use/Division
Modulus () Binary Use % for remainder
Binders

Bind1st and bind2nd can be bound in two ways. They can bind one of the parameters of a binary function object to a known object to obtain a one-dimensional function object. For example, to search for a position equal to 372 in vector <int> V, I can bind 372 to the first or second parameter of performance_to <int>:

Int <br/> main (INT argc, char ** argv) <br/>{< br/> vector <int> V; <br/> for (INT I = 0; I <1000; ++ I) <br/>{< br/> v. push_back (I); <br/>}< br/> vector <int >:: iterator it; <br/> it = find_if (v. begin (), V. end (), bind1st (pai_to <int> (), 372); <br/> STD: cout <* It <STD: Endl; <br/> return 0; <br/>}< br/>

In fact, here bind1st and bind2nd are not function objects, but just template functions. These two functions return function objects of the binder1st type and binder2nd type respectively. The following code makes it easy to understand:

// Bind1st <br/> template <class op> <br/> class binder1st: Public unary_function <br/> <typename OP: second_argument_type, <br/> typename OP :: result_type> <br/>{< br/> op _; <br/> typename OP: first_argument_type first_arg _; </P> <p> public: <br/> binder1st (const op & OP, <br/> const typename OP: first_argument_type & <br/> first_arg): op _ (OP ), <br/> first_arg _ (first_arg) {}</P> <p> typename OP: result_type operator () <br/> (const typename OP: second_argument_type & Arg) const <br/>{< br/> return op _ (first_arg _, ARG); <br/>}< br/> }; </P> <p> template <class op, class Arg> <br/> inline binder1st <OP> bind1st (const op & OP, <br/> const Arg & Arg) <br/>{< br/> return binder1st <OP> (OP, ARG ); <br/>}</P> <p> // bind2nd <br/> template <class op> <br/> class binder2nd: public unary_function <br/> <typename OP: first_argument_type, <br/> typename OP: result_type> <br/>{< br/> op _; <br/> typename OP: second_argument_type second_arg _; </P> <p> Public: <br/> binder2nd (const op & OP, <br/> const typename OP:: second_argument_type & <br/> second_arg): op _ (OP), <br/> second_arg _ (second_arg) {}</P> <p> typename OP :: result_type operator () (const typename <br/> OP: argument_type & Arg) const <br/>{< br/> return op _ (ARG, second_arg _); <br/>}< br/>}; </P> <p> template <class op, class Arg> <br/> inline binder2nd <OP> bind2nd (const op & OP, <br/> const Arg & Arg) <br/>{< br/> return binder2nd <OP> (OP, ARG); <br/>}< br/>Negaters

Negater is designed for predicate, which simply reverse the return value of predicate. There are two negater, not1 and not2, which are used to reverse the values of one dollar and binary predicate.

Member function adapters

Sometimes, you may want algorithms to call the member functions of container elements, rather than external functions. Because the external cannot change the state in the object, and the internal functionUsuallyHigher efficiency. For example, swap (string, string) always does not have string. Swap (string) fast. For example, sort cannot sort the list. In this case, only list. Sort () can be used to sort the list. At this time, you need to use a certain method to convert the functions inside the object into function objects. Such function objects are called member function adapters. In fact, the preceding binder is also an adapter. See the following example:

Int <br/> main (INT argc, char ** argv) <br/>{< br/> vector <list <int> V; <br/> v. push_back (list <int> (); <br/> vector <list <int> >:: iterator it; <br/> for (IT = v. begin (); it! = V. end (); ++ it) <br/>{< br/> for (INT I = 0; I <20; ++ I) <br/>{< br/> (* it ). insert (* it ). begin (), I); <br/>}< br/> for_each (v. begin (), V. end (), STD: mem_fun_ref (& list <int >:: sort); <br/> for (IT = v. begin (); it! = V. End (); ++ it) <br/>{< br/> for (list <int >:: iterator lt; lt! = (* It ). end (); ++ lt) <br/>{< br/> STD: cout <* lt <STD: Endl; <br/>}< br/> return 0; <br/>}< br/>

In the preceding example, traverse the vector <list <int> and sort the linked list. The member function adapter mem_fun_ref is used, and the function objects returned by it are referenced as parameters of the List <int> object. Another mem_fun parameter is the pointer to the list <int> object.

 

 

 

Original post address

Http://www.cnblogs.com/weiqubo/archive/2011/02/16/1956552.html

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.