ptr_fun/mem_fun/mem_fun_ref


背景介绍:当使用STL中的算法时,由于算法需要的回调函数既可以是普通函数也可以是仿函数,加入回调函数是普通函数,且算法对于函数的参数有一定要求,然而这个要求却限制了我们的需要,我们需要再另外在回调函数中加入参数时。

1、首先我们应当将普通函数转变为仿函数(函数对象)

2、在通过绑定适配器将仿函数的二元变为一元

因此将普通函数转变为仿函数的过程我们同样需要一种适配器即ptr_fun/mem_fun/mem_fun_ref三种

一、ptr_fun

将普通函数转变为仿函数

#include
#include
#include
#include
using namespace std;
//取反适配器
//not2二元取反适配器

bool compare(int a,int b)
{
    return a > b;
};

void output(int a,int b)
{
    cout << a+b << endl;
};

void ori_output(int a)
{
    cout << a << endl;
};
int main()
{
    vector<int> v;
    for (int i = 0; i < 5; i++)
    {
        v.push_back(rand() % 100);
    }
    sort(v.begin(), v.end(), ptr_fun(compare));
    for_each(v.begin(), v.end(), ori_output);
    for_each(v.begin(), v.end(), bind2nd((ptr_fun(output)),2));
}

二、mem_fun_ref

如果使用普通函数作为回调函数存在一种问题,即函数无法使用与之有关的变量,而且通过设置全局变量的方式由不太妥当,因此我们使用普通的类内方法或者结构体中的方法作为回调函数。再将类内的方法或结构体中的方法转变为函数对象

类内方法转变为仿函数(一元)

class Func
{
public:
    Func(int a)
    {
        this->id = a;
    }
public:
    int id;
public:
    void print()
    {
        cout << id << endl;
    }
};
int main()
{
    vectorv;
    Func f1(1);
    v.push_back(f1);
    Func f2(2);
    v.push_back(f2);
    for_each(v.begin(), v.end(),mem_fun_ref(&Func::print));
    return 0;
}

类内方法转变为仿函数(二元)

class Func:public binary_function<int,int,void>
{
public:
    Func(int a)
    {
        this->id = a;
    }
public:
    int id;
public:
    void print(int x) const
    {
        cout << id + x << endl;
    }
};
int main()
{
    vectorv;
    Func f1(1);
    v.push_back(f1);
    Func f2(2);
    v.push_back(f2);
    //for_each(v.begin(), v.end(), mem_fun_ref(&Func::print));
    for_each(v.begin(), v.end(), bind2nd(mem_fun_ref(&Func::print), 10));
    return 0;
}

 注意:对于类内方法使用绑定适配器,该类需要继承binary_function的基类,继承时的模板申明同理,在上面的例子中模板申明为int,int,void原因是第一个参数为类内的公有成员,因此我们不用在方法的形参处写出,但是模板申明时必须进行申明

二、mem_fun

mem_fun与mem_fun_ref的功能一模一样,只不过使用mem_fun_ref的时候,容器内存放的是自定义的数据类型的指针。

int main()
{
    vectorv;
    Func f1(1);
    v.push_back(&f1);
    Func f2(2);
    v.push_back(&f2);
    for_each(v.begin(), v.end(), mem_fun(&Func::print));
    return 0;
}