BZ易风

导航

 

函数适配器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));     //打印

}

结果:

 

posted on 2021-08-28 09:31  BZ易风  阅读(37)  评论(0编辑  收藏  举报