您的位置:首页 > 其它

函数对象适配器

2018-03-08 12:46 169 查看
/*
函数对象适配器
函数对象适配器是完成一些配接工作,这些配接包括绑定(bind),否定(negate),
以及对一般函数或成员函数的修饰,使其成为函数对象,重点掌握函数对象适配器(红色字体);

bind1st:将参数绑定为函数对象的第一个参数
bind2nd:将参数绑定为函数对象的第二个参数
not1:对一元函数对象取反
not2:对二元函数对象取反
ptr_fun仿函数适配器
mem_fun mem_fun_ref成员函数适配器
*/
# include <iostream>
# include <vector>
# include <algorithm>
# include <cstdlib>
# include <ctime>
# include <functional>//绑定适配器的头文件
using namespace std;

struct MyPrint : public binary_function<int, int, void>
{
void operator()(int v,int val)const 
{
cout << "v:" << v << " val:" << val << endl;
cout << v + val << endl;
}
};

//仿函数适配器 bindlst bind2nd 绑定适配器
void test01()
{
vector<int> v;
for(int i = 0; i < 10; i++)
{
v.push_back(i);
}
MyPrint p;
for_each(v.begin(), v.end(), bind1st(p, 200));
//在需要传俩个参数的时候因为它只有一个参数所以需要绑定适配器,for_each只有1个参数
//绑定适配器的作用是将一个二元函数对象转变成1元函数对象

//bindlst bind2nd 区别
//bind1st,将参数200绑定为函数对象的第一个参数
//bind2nd,将参数200绑定为函数对象的第二个参数
}

# if 1
struct MyPrint02
{
void operator()(int v)const 
{

cout << v << " ";
}

};
# endif

struct MyCompare : public binary_function <int , int, bool>
{
bool operator()(int v1, int v2)const
{
if(v1 != v2)

4000
return v1 > v2;//从大到小
}
};

struct MyGreater5 : public unary_function<int, bool>
{
bool operator()(int v)const
{
return v > 5;
}
};

//仿函数适配器 not1 not2 取反适配器
void test02()
{
vector<int> v;
srand((unsigned)time(NULL));
for(int i = 0; i < 10; i++)
{
v.push_back(rand() % 100);
}
for_each(v.begin(), v.end(), MyPrint02());
cout << endl;
/*
sort的比较函数有个弱序化的限制
就vs里有
就是说比较的两个数,如果相等的话,应该返回false
所以比较的时候要加上v1 != v2不然会挂掉
*/
sort(v.begin(), v.end(), not2(MyCompare()));
for_each(v.begin(), v.end(), MyPrint02());
cout << endl;

//not2 not1区别
//如果对二元谓词取反,用not2 继承类binary_function
//如果对一元谓词取反,用not1 继承类unary_function

//查找第一个大于5的,返回第一个大于5的迭代器
//用了not1反转
vector<int>:: iterator it = find_if(v.begin(), v.end(), not1(MyGreater5()));
if(it == v.end())
{
cout << "没有找到" << endl;
}
else
{
cout << *it << endl;
}
}

//仿函数适配器 ptr_fun
//因为普通函数没有办法被绑定所以必须转换成函数对象
void MyPrint03(int val1, int val2)
{
cout << "val1:" <<val1 << " val2:" << val2 << endl;
cout << "val1 + val2 = " << val1 + val2 << 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(ptr_fun(MyPrint03), 10));
cout << endl;
}

//成员函数适配器 mem_fun mem_fun_ref
class Person
{
public:
Person(int age, int id):age(age), id(id)
{};
void show()
{
cout << "age:" << age << " " << "id:" << id << endl;
}
public:
int age;
int id;
};

void test04()
{
//如果容器中存放的对象或者对象指针,我们for_each算法打印的时候,调用自己提供的打印函数

vector<Person> v;
Person p1(10, 20), p2(30, 40), p3(50, 60);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);

//格式:&类名::函数名
for_each(v.begin(), v.end(), mem_fun_ref(&Person::show));

cout << "----------" << endl;
vector<Person*> v1;
v1.push_back(&p1);
v1.push_back(&p2);
v1.push_back(&p3);
for_each(v1.begin(), v1.end(), mem_fun(&Person::show));

//mem_fun和mem_fun_ref区别?
//如果存放的是对象指针 使用mem_fun
//如果使用的是对象 使用mem_fun_ref

}

int main(int argc, char *argv[])
{
//test01();
//test02();
//test03();
test04();

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: