• STL笔记:函数配接器(Function adapters)


    一:STL预定义函数配接器的使用

    STL预定义的函数配接器
    1. bind1st(op, value)
    2. bind2st(op, value)
    3. not1(param)
    4. not2(param1,param2)

    函数配接器可以将仿函数和另一个仿函数结合起来。
    函数配接器本身也是仿函数。

    二元函数配接器示例:
    find_if( coll.begin(), coll.end(), bind2nd(greater<int>(),42) );
    以上例句中,bind2nd将仿函数greater<int>()和第二个参数整型数42结合起来,查找条件就变成了“大于42”。
    其中greater<int>为STL预定义的仿函数,接收两个参数比较,第一个参数为coll中元素,第二个参数42作为greater<int>的内部参数保存,上面的语句相当于以下伪代码的逻辑(注意只是相等逻辑,非STL实现):

    greater<int>    functorGreater;     //在find_if语句内部,仿函数会创建一个实例对象
    for(std::vector<int>::const_iterator It = coll.begin();    It != coll.end(); ++It )
    {
        if( functorGreater(*It,42) )     //调用仿函数greater<int>内部的重载操作符"()"完成比较操作
        return It;
    
        return coll.end();
    }

    类似的,一元函数配接器:

    find_if( coll.begin(),    coll.end(),    bind1nd(greater<int>(),42)    );

    只是想当把以上伪代码中的

    if( functorGreater(*It,42) )
    改成
    if( functorGreater(42,*It) )
    可见,仿函数命名bind1st,bind2nd意思是指定第几个元素是要作为“被绑定的仿函数”的内部参数的。


    not1()将结果取反:

    find_if( coll.begin(),    coll.end(),    not1(bind2nd(greater<int>(),42))    );

    返回小于等于42的值。

    not1()与not2()区别只是后者用于接收两个形参的表达式: not2(op) //这里的op接收两个形参,not2将op的返回值取反

    二:针对成员函数的函数配接器
    成员函数的函数配接器(注意op均为const),同普通函数配接器,只是被配接的函数是类的成员函数。
    1.mem_fun_ref(op)
    2.mem_fun(op)

    示例(Win7 64 + Visual studio 2010):

    #include <iostream>
    #include <vector>
    #include <functional>
    #include <algorithm>
    #include <iterator>
    
    using namespace::std;
    
    class TestClass
    {
    public:
        TestClass(int i):index(i){}
    
    void print() const
    {
        cout<<"TestClass"<<index<<endl;;
    }
    
    int operator()()
    {
        return index++;
    }
    
    private:
        int index;
    };
    
    int main()
    {
        vector<TestClass> testVector;
    
        generate_n(back_inserter(testVector),10,TestClass(1));
        for_each(testVector.begin(),testVector.end(),             mem_fun_ref(&TestClass::print));    //遍历输出
    
        return 0;
    }

    以上代码中,mem_fun_ref调用了TestClass中的print成员函数,而且print函数必须为const。
    mem_fun和mem_fun_ref区别在于,后者调用的是类引用类型,前者是指针类型:
    若testVector类型为vector<TestClass*>
    则需要调用mem_fun(&TestClass::print)

    三:一般函数的函数配接器
    参考成员函数的配接器,基本没啥不同。
    如有全局函数

    void printTestClass(TestClass& refTC)
    {
        refTC.print();
    }

    调用:

    for_each(testVector.begin(),testVector.end(), ptr_fun( printTestClass ) );

    四:自定义仿函数的函数配接器
    自定义仿函数需要提供类型成员来指定参数和返回值类型,可继承以下STL中定义的模板来确定规范化:

    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 first_argument_type;
    typedef Arg2 second_argument_type;
    typedef Result result_type;
    }
  • 相关阅读:
    《大道至简》读后有感
    关于jQuery放置位置的问题01
    javascript基础
    层叠样式表与css3基础
    经典sql语句
    java开发中的23种设计模式
    struts2漏洞以及测试
    离开贴吧大概会写下博客吧
    Set介绍
    小知识点
  • 原文地址:https://www.cnblogs.com/acros/p/3244861.html
Copyright © 2020-2023  润新知