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