• STL适配器


    函数适配器bind1st bind2nd

    现在我有这个需求 在遍历容器的时候,我希望将容器中的值全部加上100之后显示出来,怎么做?

    我们直接给函数对象绑定参数 编译阶段就会报错

    for_each(v.begin(), v.end(), bind2nd(myprint(),100));

    如果我们想使用绑定适配器,需要我们自己的函数对象继承binary_function 或者 unary_function

    根据我们函数对象是一元函数对象 还是二元函数对象

    函数适配器

    • 0~9 加起始值 进行输出 用户提供起始值
    • bind2nd  绑定
    • 继承  binary_function<参数类型1,参数类型2,返回值类型>
    • const修饰 operator() 
    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    using namespace std;
    #include <vector>
    #include <algorithm>
    #include <functional>
    class myPrint:public binary_function<int,int, void> //虚继承类binary_function<参数类型1,参数类型2,返回值类型>
    {
    public:
        void operator()(int v, int start)const  //const修饰
        {
            cout << "v=" << v << " start=" << start << " v+start=" << v + start << endl;
        }
    };
    void test01()
    {
        vector<int>v;
        for (int i = 0; i < 10; i++)
        {
            v.push_back(i);
        }
        cout << "请输入起始数字:" << endl;
        int num;
        cin >> num;
        //for_each(v.begin(), v.end(), bind1st(myPrint(), num));  //bind1st 将参数绑定为函数对象的第一个参数 num作为v  而v迭代出来的数据作为start
        for_each(v.begin(), v.end(), bind2nd(myPrint(), num));    //bind2nd 将参数绑定为函数对象的第二个参数 num作为start数据
    
    }
    int main()
    {
        test01();
        system("Pause");
        return 0;
    }

    bind1st结果:

    bind2nd结果:

    取反适配器

    • not1  一元 找出小于5 
    • not2 二元  排序  not2(  less<int>() ) 从大到小 相当于  greater<int>()
    //取反适配器
    class GreaterThenFive:public unary_function<int, bool>  //取反适配器继承于unary_function
    {
    public:
        bool operator()(int v)const
        {
            return v > 5;
        }
    };
    void test02()
    {
        //一元取反
        vector<int>v;
        for (int i = 0; i < 10; i++)
        {
            v.push_back(i);
        }
        //查找大于5的数字
        vector<int>::iterator pos = find_if(v.begin(), v.end(), GreaterThenFive());
        if (pos != v.end())         //6
        {
            cout << "找到大于5的数字: " << *pos << endl;
        }
        else
        {
            cout << "未找到" << endl;
        }
    
        //改变需求 查找小于5的数字
        pos = find_if(v.begin(), v.end(), not1(GreaterThenFive()));
        if (pos != v.end())         //0
        {
            cout << "找到小于5的数字: " << *pos << endl;
        }
        else
        {
            cout << "未找到" << endl;
        }
    
        //绑定取反
        pos = find_if(v.begin(), v.end(), not1(bind2nd(greater<int>(), 5)));   //利用内建函数greater v迭代器作为1值 5作为2值做取反
        if (pos != v.end())         //0
        {
            cout << "找到小于5的数字: " << *pos << endl;
        }
        else
        {
            cout << "未找到" << endl;
        }
    }

    结果:

    函数指针适配

    • 关键字 ptr_fun
    • 将函数指针适配成函数对象
    //普通函数指针适配
    void myPrint02(int v, int start)
    {
        cout << v + start << endl;
    }
    void test03()
    {
        vector<int>v;
        for (int i = 0; i < 10; i++)
        {
            v.push_back(i);
        }
        //将函数指针适配成函数对象
        //关键字 ptr_fun
        //for_each(v.begin(), v.end(), bind2nd(myPrint02,100));     //error 普通函数不能绑定数值
        for_each(v.begin(), v.end(), bind2nd(ptr_fun(myPrint02), 100));  //把普通函数适配成函数对象 然后绑定起始值
    }

    结果:

    成员函数适配器

    • 如果容器存放的是对象指针,  那么用mem_fun
    • 如果容器中存放的是对象实体,那么用mem_fun_ref
    //成员函数适配器
    class Person
    {
    public:
        Person(string name, int age)
        {
            this->m_Age = age;
            this->m_Name = name;
        }
        void showPerson()
        {
            cout << "成员函数:姓名: " << m_Name << " 年龄:" << m_Age << endl;
        }
        void plusAge()
        {
            this->m_Age += 100;
        }
        string m_Name;
        int m_Age;
    };
    void test04()
    {
        vector<Person>v;
        Person p1("猴子", 500);
        Person p2("猪头", 550);
        Person p3("水怪", 600);
        Person p4("和尚", 1000);
        v.push_back(p1);
        v.push_back(p2);
        v.push_back(p3);
        v.push_back(p4);
    
        //for_each(v.begin(), v.end(), &Person::showPerson);      //error 提示项不会计算为接收1个参数的函数 需要适配器
        //成员函数适配器
        // mem_fun_ref
        for_each(v.begin(), v.end(), mem_fun_ref(&Person::showPerson));     //打印
        for_each(v.begin(), v.end(), mem_fun_ref(&Person::plusAge));        //增寿  没个成员都执行一套逻辑
        for_each(v.begin(), v.end(), mem_fun_ref(&Person::showPerson));     //增寿后打印
    }

    结果:

    对象指针类型

    void test05()
    {
        vector<Person*>v;
        Person p1("猴子", 500);
        Person p2("猪头", 550);
        Person p3("水怪", 600);
        Person p4("和尚", 1000);
        v.push_back(&p1);
        v.push_back(&p2);
        v.push_back(&p3);
        v.push_back(&p4);
        //成员函数适配器 数据类型为对象指针
        // mem_fun
        for_each(v.begin(), v.end(), mem_fun(&Person::showPerson));     //打印
    
    }

    结果:

  • 相关阅读:
    iOS
    流媒体服务之基于RTMP的本地Nginx服务器和VLC安装
    iOS-搭建基于RTMP的本地Nginx服务器(VLC播放器免费安装)+ 推流LFLiveKit直播框架集成 + ijkplayer拉流框架编译集成
    hexo主题next 7.X版本配置美化
    Centos记录所有用户登录和操作的详细日志
    二进制搭建kubernetes多master集群【四、配置k8s node】
    二进制搭建kubernetes多master集群【三、配置k8s master及高可用】
    二进制搭建kubernetes多master集群【二、配置flannel网络】
    二进制搭建kubernetes多master集群【一、使用TLS证书搭建etcd集群】
    二进制搭建kubernetes多master集群【开篇、集群环境和功能介绍】
  • 原文地址:https://www.cnblogs.com/yifengs/p/15195968.html
Copyright © 2020-2023  润新知