Imitation functions of STL learning path

Source: Internet
Author: User

Imitation functions (or function objects) in STL: similar types can be implemented. The most direct form of calling a function is the return value function name (parameter list ), similar functions are used to implement the operator () operator.

At the same time, STL also provides a powerful adapter for the imitation functions, that is, the adapter Adapters. These Adapters are also imitation functions, and the call method is similar to the function. Furthermore, these adapters can be bound, combined, and adapted with functions, functions, and adapters to achieve more complex functions.

This part should be the simplest part of STL, and the implementation is relatively simple. In addition, the C ++ 11 standard makes great adjustments to this part, so we will not consider it first. Now, we use it as an example of learning a template.

# Ifndef TESTFUNCTIONAL_H # define TESTFUNCTIONAL_Hnamespace Test {template <class _ Arg, class _ Result> struct unary_function {typedef _ Arg argument_type; typedef _ Result result_type;}; template <class _ Arg1, class _ Arg2, class _ Result> struct binary_function {typedef _ Arg1 partition; typedef _ Arg2 second_argument_type; typedef _ Result result_type ;}; template <class _ Tp> struct plus: public binary_functi On <_ Tp, _ Tp, _ Tp> {_ Tp operator () (const _ Tp & _ x, const _ Tp & _ y) const {return _ x + _ y ;}; template <class _ Tp> struct minus: public binary_function <_ Tp, _ Tp, _ Tp> {_ Tp operator () (const _ Tp & _ x, const _ Tp & _ y) const {return _ x-_ y ;}; template <class _ Tp> struct multiplies: public binary_function <_ Tp, _ Tp, _ Tp> {_ Tp operator () (const _ Tp & _ x, const _ Tp & _ y) const {return _ x * _ y ;}}; template <class _ Tp > Struct divides: public binary_function <_ Tp, _ Tp, _ Tp> {_ Tp operator () (const _ Tp & _ x, const _ Tp & _ y) const {return _ x/_ y ;}; template <class _ Tp> struct modulus: public binary_function <_ Tp, _ Tp, _ Tp> {_ Tp operator () (const _ Tp & _ x, const _ Tp & _ y) const {return _ x % _ y ;}; template <class _ Tp> struct negate: public unary_function <_ Tp, _ Tp> {_ Tp operator () (const _ Tp & _ x) const {return-_ x ;}}; templa Te <class _ Tp> struct functions _to: public binary_function <_ Tp, _ Tp, bool> {bool operator () (const _ Tp & _ x, const _ Tp & _ y) const {return _ x = _ y ;}}; template <class _ Tp> struct not_0000_to: public binary_function <_ Tp, _ Tp, bool> {bool operator () (const _ Tp & _ x, const _ Tp & _ y) const {return _ x! = _ Y ;}}; template <class _ Tp> struct greater: public binary_function <_ Tp, _ Tp, bool> {bool operator () (const _ Tp & _ x, const _ Tp & _ y) const {return _ x> _ y ;}}; template <class _ Tp> struct less: public binary_function <_ Tp, _ Tp, bool> {bool operator () (const _ Tp & _ x, const _ Tp & _ y) const {return _ x <_ y ;}}; template <class _ Tp> struct greater_equal: public binary_function <_ Tp, _ Tp, bool> {bool opera Tor () (const _ Tp & _ x, const _ Tp & _ y) const {return _ x >=_ _ y ;}}; template <class _ Tp> struct less_equal: public binary_function <_ Tp, _ Tp, bool> {bool operator () (const _ Tp & _ x, const _ Tp & _ y) const {return _ x <= _ y ;}}; template <class _ Tp> struct logical_and: public binary_function <_ Tp, _ Tp, bool> {bool operator () (const _ Tp & _ x, const _ Tp & _ y) const {return _ x & _ y ;}}; template <class _ Tp> Struct logical_or: public binary_function <_ Tp, _ Tp, bool> {bool operator () (const _ Tp & _ x, const _ Tp & _ y) const {return _ x | _ y ;}}; template <class _ Tp> struct logical_not: public unary_function <_ Tp, bool> {bool operator () (const _ Tp & _ x) const {return! _ X ;}; template <class _ Predicate> class unary_negate: public unary_function <typename _ Predicate: argument_type, bool> {protected: _ Predicate _ M_pred; public: explicit unary_negate (const _ Predicate & _ x): _ M_pred (_ x) {} bool operator () (const typename _ Predicate: argument_type & _ x) const {return! _ M_pred (_ x) ;}}; template <class _ Predicate> inline unary_negate <_ Predicate> not1 (const _ Predicate & _ pred) {return unary_negate <_ Predicate> (_ pred);} template <class _ Predicate> class binary_negate: public binary_function <typename _ Predicate: role, typename _ Predicate: second_argument_type, bool> {protected: _ Predicate _ M_pred; public: explicit binary_negate (const _ Predicate & _ x): _ M_pred (_ x) {} B Ool operator () (const typename _ Predicate: first_argument_type & _ x, const typename _ Predicate: second_argument_type & _ y) const {return! _ M_pred (_ x, _ y) ;}; template <class _ Predicate> inline binary_negate <_ Predicate> not2 (const _ Predicate & _ pred) {return binary_negate <_ Predicate> (_ pred);} // bind the first operand of a binary operator class, that is, call operator () the parameter needs to pass the second operand template <class _ Operation> class binder1st: public unary_function <typename _ Operation: second_argument_type, // derived from the unary operator class, // The parameter type of the unary operator is the second operand type of the binary operator class, which is the same as the operator () parameter type to be called. typename _ Operation: result_type> {protected: _ Operation _ op; typename _ Operation: first_argument_type value; public: binder1st (const _ Operation & op, const typename _ Operation: first_argument_type & _ x ): _ op (op), value (_ x) {} typename _ Operation: result_type operator () (const typename _ Operation: second_argument_type & _ y) const {return _ op (value, _ y) ;}; template <class _ Operation, class _ Tp> inline binder1st <_ Operation> bind1st (const _ Operation & op, const _ Tp & _ x) {typedef typename _ Operation: first_argument_type _ Arg1_type; return binder1st <_ Operation> (op, _ Arg1_type (_ x ));} // bind the second operand of a binary operator class, that is, to call the operator () parameter, you must pass the first operand template <class _ Operation> class binder2nd: public unary_function <typename _ Operation:: first_argument_type, // derived from the unary operator class, // The parameter type of the unary operator is the second operand type of the binary operator class, and the operator () to be called () same parameter type: typename _ Operation: result_type> {protected: _ Operation _ op; typename _ Operation: second_argument_type value; public: binder2nd (const _ Operation & op, const typename _ Operation: second_argument_type & _ y): _ op (op), value (_ y) {} typename _ Operation: result_type operator () (const typename _ Operation:: first_argument_type & _ x) const {return _ op (_ x, value) ;}; template <class _ Operation, class _ Tp> inline binder2nd <_ Operation> bind2nd (const _ Operation & op, const _ Tp & _ y) {typedef typename _ Operation: second_argument_type _ Arg2_type; return binder2nd <_ Operation> (op, _ Arg2_type (_ y);} // f (g (x) template <class _ Operation1, class _ Operation2> class unary_compose: public unary_function <typename _ Operation2: Operator, typename _ Operation1: result_type> {protected: _ Operation1 _ M_op1; _ Operation2 _ M_op2; public: const _ Operation1 & op1, const _ Operation2 & op2): _ M_op1 (op1), _ M_op2 (op2) {} typename _ Operation1: result_type operator () (const typename _ Operation2 :: argument_type & _ x) const {return _ M_op1 (_ M_op2 (_ x) ;}; template <class _ Operation1, class _ Operation2> inline unary_compose <_ Operation1, _ Operation2> compose1 (const _ Operation1 & op1, const _ Operation2 & op2) {return unary_compose <_ Operation1, _ Operation2> (op1, op2 );} // f (g1 (x), g2 (x) template <class _ Operation1, class _ Operation2, class _ Operation3> class binary_compose: binary_function <typename _ Operation2: argument_type, typename _ Operation3: argument_type, typename _ Operation1: result_type> {protected: _ Operation1 _ M_op1; _ Operation2 _ M_op2; _ Operation3 _ M_op3; public: binary_compose (const _ Operation1 & op1, const _ Operation2 & op2, const _ Operation3 & op3): _ M_op1 (op1), _ M_op2 (op2), _ M_op3 (op3) {} typename _ Operation1: result_type operator () (typename const _ Operation2: argument_type & _ x) const {return _ M_op1 (_ M_op2 (_ x ), _ M_op3 (_ x) ;}; template <class _ Operation1, class _ Operation2, class _ Operation3> inline binary_compose <_ Operation1, _ Operation2, _ Operation3> compose2 (const _ Operation1 & op1, const _ Operation2 & op2, const _ Operation3 & op3) {return binary_compose <_ Operation1, _ Operation2, _ Operation3> (op1, op2, op3);} // Convert a common single-parameter function to an object template <class _ Arg, class _ Result> class pointer_to_unary_function: public unary_function <_ Arg, _ Result> {protected: _ Result (* _ pfn) (_ Arg); public: pointer_to_unary_function () {} explicit pointer_to_unary_function (_ Result (* pfn) (_ Arg): _ pfn (pfn) {}_ Result operator () (_ Arg _ x) const {return _ pfn (_ x) ;}}; template <class _ Arg, class _ Result> inline pointer_to_unary_function <_ Arg, _ Result> ptr_fun (_ Result (* pfn) (_ Arg) {return pointer_to_unary_function <_ Arg, _ Result> (pfn);} // normal 2 parameter function to convert the object template <class _ Arg1, class _ Arg2, class _ Result> class pointer_to_binary_function: public binary_function <_ Arg1, _ Arg2, _ Result> {protected: _ Result (* _ pfn) (_ Arg1, _ Arg2); public: pointer_to_binary_function (_ Result (* pfn) (_ Arg1, _ Arg2): _ pfn (pfn) {}_ Result operator () (_ Arg1 _ x, _ Arg2 _ y) const {return _ pfn (_ x, _ y) ;}}; template <class _ Arg1, class _ Arg2, class _ Result> inline pointer_to_binary_function <_ Arg1, _ Arg2, _ Result> ptr_fun (_ Result (* pfn) (_ Arg1, _ Arg2) {return pointer_to_binary_function <_ Arg1, _ Arg2, _ Result> (pfn );} // class function, class object pointer template <class _ Ret, class _ Tp> class mem_fun_t: public unary_function <_ Tp *, _ Ret> {protected: _ Ret (_ Tp:: * _ pfn) (); public: explicit mem_fun_t (_ Ret (_ Tp: * pfn) (): _ pfn (pfn) {} _ Ret operator () (_ Tp * _ p) const {return (_ p-> * _ pfn) () ;}; // class const function, class object pointer template <class _ Ret, class _ Tp> class const_mem_fun_t: public unary_function <const _ Tp *, _ Ret> {protected: _ Ret (_ Tp: * _ pfn) () const; public: explicit const_mem_fun_t (_ Ret (_ Tp: * pfn) () const): _ pfn (pfn) {} _ Ret operator () (const _ Tp * _ p) const {return (_ p-> * _ pfn) () ;}}; // class function, class object reference template <class _ Ret, class _ Tp> class mem_fun_ref_t: public unary_function <_ Tp, _ Ret> {protected: _ Ret (_ Tp: * _ pfn) (); public: explicit mem_fun_ref_t (_ Ret (_ Tp :: * pfn) (): _ pfn (pfn) {}_ Ret operator () (_ Tp & _ p) const {return (_ p. * _ pfn) () ;}}; // class const function, class object references template <class _ Ret, class _ Tp> class const_mem_fun_ref_t: public unary_function <_ Tp, _ Ret> {protected: _ Ret (_ Tp: * _ pfn) (); public: explicit const_mem_fun_ref_t (_ Ret (_ Tp: * pfn) () const ): _ pfn (pfn) {}_ Ret operator () (const _ Tp & _ p) const {return (_ p. * _ pfn) () ;}}; // The parameter is omitted ...... template <class _ Ret, class _ Tp> inline mem_fun_t <_ Ret, _ Tp> mem_fun (_ Ret (_ Tp: * pfn )()) {return mem_fun_t <_ Ret, _ Tp> (pfn);} template <class _ Ret, class _ Tp> inline const_mem_fun_t <_ Ret, _ Tp> mem_fun (_ Ret (_ Tp: * pfn) () const) {return const_mem_fun_t <_ Ret, _ Tp> (pfn);} template <class _ Ret, class _ Tp> inline mem_fun_ref_t <_ Ret, _ Tp> mem_fun_ref (_ Ret (_ Tp: * pfn) () {return mem_fun_ref_t <_ Ret, _ Tp> (pfn);} template <class _ Ret, class _ Tp> inline const_mem_fun_ref_t <_ Ret, _ Tp> mem_fun_ref (_ Ret (_ Tp: * pfn) () const) {return const_mem_fun_ref_t <_ Ret, _ Tp> (pfn) ;}# endif // TESTFUNCTIONAL_H
I have written a part about implementation, and some similar laziness is omitted. If you want to see the full version, you can download the source code. In addition, I did some tests on it:

# Include "TestFunctional. h "# include <stdlib. h ># include <iostream> using namespace std; class TestClass {public: void testFun () {cout <"testfun" <endl;} void testFunC () const {cout <"testfun1 const" <endl ;}; int main (int argc, char * argv []) {typedef Test: less <int> Op_less; int opVal = 6; int val = 4; // 6 <xTest: binder1st <Op_less> bd1 = Test: bind1st <Op_less, double> (Op_less (), opVal ); cout <opVal <"less than" <val <'\ t' <boolalpha <bd1 (val) <endl; // x <6, that is, 6> xTest: binder2nd <Op_less> bd2 = Test: bind2nd <Op_less, double> (Op_less (), opVal ); cout <val <"less than" <opVal <'\ t' <boolalpha <bd2 (val) <endl; // f (x) = 3 * x, g (x) = x + 2 => f (g (x) = (x + 2) * 3; typedef Test :: plus <int> Op_plus; typedef Test: multiplies <int> Op_mult; cout <Test: compose1 <Test: binder1st <Op_mult>, Test :: binder2nd <Op_plus> (Test: bind1st <Op_mult, int> (Op_mult (), 3), Test: bind2nd <Op_plus, int> (Op_plus (), 2 )) (val) <endl; // f (x, y) = x * y, g1 (x) = x + 2, g2 (x) = 6-x => f (g1 (x), g2 (x) = (x + 2) * (6-x) typedef Test :: minus <int> Op_minus; cout <Test: compose2 <Op_mult, Test: binder2nd <Op_plus>, Test: binder1st <Op_minus> (Op_mult (), Test :: bind2nd <Op_plus, int> (Op_plus (), 2), Test: bind1st <Op_minus, int> (Op_minus (), 6) (val) <endl; testClass tc1; Test: mem_fun (& TestClass: testFun) (& tc1); Test: mem_fun (& TestClass: testFunC) (& tc1 ); system ("pause"); return 1 ;}

Add the test results together. I didn't test it in gcc, but just ran it in vs2010.


The code and examples are very simple, and only serve as a learning record for understanding a part of STL.

Imitation functions of STL learning path

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.