zoukankan      html  css  js  c++  java
  • 函数配接器

    概念

    所谓的“函数配接器”是指能够将仿函数另一个仿函数(或者某个值,或者另一个仿函数)结合起来的仿函数。函数配接器也声明与<functional>中。

    通过函数配接器,我们可以把多个仿函数结合起来,形成强大的表达式,这种编程方式叫做functional composition(功能复合、函数复合)。

    STL中预定义了四种类型的函数配接器,如图表1,函数配接器使用效果见例子1.
    例子1
    /****************************************************************
    *函数名称:FuncAdapter
    *功    能:预定义的函数配接器举例
    *作    者:Jin
    *日    期:2016年6月7日
    ****************************************************************/
    void FuncAdapter()
    {
        typedef vector<int> IntVector;
        IntVector Container;
    
        Container.push_back(10);
        Container.push_back(15);
        Container.push_back(20);
        Container.push_back(9);
    
        cout << "element in the container is: ";
        copy(Container.begin(), Container.end(), ostream_iterator<int>(cout, " "));
        cout << endl;
    
        //bind2nd范式: param > 15
        //output:1个
        int nNumber1 = count_if(Container.begin(), 
                               Container.end(),
                               bind2nd(greater<int>(), 15));
        cout << "The number of elements in Container greater than 15 is: "
             << nNumber1 << endl;
        
        //bind1st范式: 15 > param
        int nNumber2 = count_if(Container.begin(), 
                                Container.end(),
                                bind1st(greater<int>(), 15));
        cout << "The number of elements in Container less than  15 is: "
             << nNumber2 << endl;
    
        // not1 bind1st范式:  !(param > 15) == (param <= 15)
        int nNumber3 = count_if(Container.begin(), 
                                Container.end(),
                                not1(bind2nd(greater<int>(), 15)));
        cout << "The number of elements in Container less than or equal to 15 is: "
             << nNumber3 << endl;
    
        sort(Container.begin(),Container.end(),less<int>());
        PrintElements(Container, "descending: ");
        //not2 范式 !op(param1, param2)
        sort(Container.begin(),Container.end(),not2(less<int>()));
        PrintElements(Container, "Ascending: ");
    }

    运行结果:



    成员函数配接器

    为了能够将类别中的成员函数和仿函数结合起来,需要是使用成员函数配接器,将成员函数转变仿函数,STL中预定义了两种成员函数配接器接口见表2.
    成员函数配接代码见例子2.

    例子2

    class Person
    {
    public:
        //member function
        void Print() const
        {
            cout << m_strName << endl;   
        }
        //member function
        void PrintWithPrefix(string strPrefix) const
        {
            std::cout << strPrefix << m_strName << endl;
        }
        //construction function
        Person(string strName):m_strName(strName){}
    
    private:
        string m_strName;
    };
    
    /****************************************************************
    *函数名称:MemberFunction
    *功    能:针对成员函数设计的函数配接器
    *作    者:Jin
    *日    期:2016年6月8日
    ****************************************************************/
    void MemberFuncAdapter()
    {
       vector<Person> PersonVector;     //vector中是对象
       vector<Person*> PtrPersonVector; //指针序列
    
       const int nMaxPerson = 5;
       string strNames[nMaxPerson] = 
       {
            "David",
            "Kangkang",
            "Hua",
            "Mike",
            "Lily"
       };
    
       for (int i = 0; i < nMaxPerson; i++)
       {
           Person per(strNames[i]);;
           PersonVector.push_back(per);
    
           Person *PtrPer = new Person(strNames[i]);
           PtrPersonVector.push_back(PtrPer);
       }
    
       //it is object in the vector: call print member function 
       for_each(PersonVector.begin(), PersonVector.end(), mem_fun_ref(&Person::Print));
       //it is object in the vector: call PrintWithPrefix member function 
       for_each(PersonVector.begin(), 
                PersonVector.end(), 
                bind2nd(mem_fun_ref(&Person::PrintWithPrefix), "person:"));
       
       cout << endl << "ptr object: " << endl;
       //it is ptr in the vector: call print member function 
       for_each(PtrPersonVector.begin(), PtrPersonVector.end(), mem_fun(&Person::Print));
       //it is ptr in the vector: call PrintWithPrefix member function 
       for_each(PtrPersonVector.begin(), 
                PtrPersonVector.end(), 
                bind2nd(mem_fun(&Person::PrintWithPrefix), "PersonName:"));
        
       //删除申请的空间
       for (unsigned i = 0; i < PtrPersonVector.size(); i++)
       {
           delete PtrPersonVector[i];
       }
    
    }
    运行效果:


    一般函数配接器

    针对非成员函数而设计的函数配接器是ptr_fun见表3,从而可以和仿函数结合起来。具体代码使用见例子3。
    例子3
    /****************************************************************
    *函数名称:CommonFuncAdapter
    *功    能:用于一般函数身上的函数配接器
    *作    者:Jin
    *日    期:2016年6月14日
    ****************************************************************/
    void CommonFuncAdapter()
    {
        vector <char*> v1;
        vector <char*>::iterator Iter1, RIter;
    
        v1.push_back ("Open");
        v1.push_back ("up");
        v1.push_back ("the");
        v1.push_back ("pearly");
        v1.push_back ("gates");
    
        cout << "Original sequence contains: " ;
        for (Iter1 = v1.begin(); Iter1 != v1.end(); Iter1++)
        {
            cout << *Iter1 << " ";
        }  
        cout << endl;
    
        // To search the sequence for "pearly"
        // use a pointer_to_function conversion
        RIter = find_if(v1.begin(),
                        v1.end(),
                        not1(bind2nd(ptr_fun(strcmp), "pearly")));
    
        if (RIter != v1.end())  
        {
            cout << "The search for 'pearly' was successful.
    ";
            cout << "The next character string is: " 
                 << *++RIter 
                 << "." 
                 << endl;
        }
    }
    运行结果:


    自定义仿函数的可配接性

    在某些情况下,我们需要编写自己的仿函数,但是希望它们能够和函数配接器搭配运用,就必须满足某些条件:

    提供一些成员函数来反映其参数和返回值的型别,STL提供了如下的数据结构:

    // TEMPLATE STRUCT unary_function
    template<class _Arg, class _Result>
    struct unary_function
    {	
    	// base class for unary functions
    	typedef _Arg argument_type;
    	typedef _Result result_type;
    };
    
    // TEMPLATE STRUCT binary_function
    template<class _Arg1, class _Arg2, class _Result>
    struct binary_function
    {	
    	// base class for binary functions
    	typedef _Arg1 first_argument_type;
    	typedef _Arg2 second_argument_type;
    	typedef _Result result_type;
    };
    仿函数上述两种形式之一,就能轻松满是“可配接”的条件,例如预定义仿函数great,less都继承了上述结构,具体“可配接”性的分析后文再单独分享。

    template<class _Ty>
    struct less: public binary_function<_Ty, _Ty, bool>
    {	
    	// functor for operator<
    	bool operator()(const _Ty& _Left, const _Ty& _Right) const
    	{	
    		// apply operator< to operands
    		return (_Left < _Right);
    	}
    };
    
    template<class _Ty>
    struct negate : public unary_function<_Ty, _Ty>
    {	
    	// functor for unary operator-
    	Ty operator()(const _Ty& _Left) const
    	{	
    		// apply operator- to operand
    		return (-_Left);
    	}
    };

  • 相关阅读:
    office 2007 验证失败的解决方法
    google开不了(解决办法)
    Mobilenet V1
    Windows10系统下IDECLion的安装与配置
    单目相机成像过程
    C++中如何在函数中返回局部变量的指针/引用/地址?
    ResNeXt论文阅读笔记.md
    Mobilenet V2
    Xception
    InceptionV4
  • 原文地址:https://www.cnblogs.com/jinxiang1224/p/8468411.html
Copyright © 2011-2022 走看看