文章目录
一.bind1st/bind2nd使用
1.bind1st/bind2nd介绍
绑定适配器 将一个二元函数对象转变成一元函数对象
bind1st bind2nd区别?
bind1st,将元素绑定为函数对象的第一个参数
bind2nd,将元素绑定为函数对象的第二个参数
头文件:#include
2.程序测试
测试用例:
将容器中每个元素都加上一个特定值,如200
namespace FunctionalTest {
//仿函数
//为了使用绑定适配器,这里需要继承binary_function<>,
//其中第一二个参数与输入类型一致,第三个返回类型
struct MyPrint : public binary_function<int, int, void> {
void operator()(int v, int val) const {
cout << " Test v:" << v << " val:" << val << endl;
cout << v + val << " "<<endl;
}
};
//仿函数适配器 bind1st bind2nd 绑定适配器
void test01() {
vector<int> v;
for (int i = 0; i < 3; i++) {
v.push_back(i);
}
int addNum = 200;
//bind1st测试
for_each(v.begin(), v.end(), bind1st(MyPrint(), addNum));
//bind2nd测试
//for_each(v.begin(), v.end(), bind2nd(MyPrint(), addNum));
cout << endl;
}
程序执行结果:
bind2nd测试:
bind1st测试:
要加的200都是在低于个元素位置
二.not1、not2使用
1.简介
not1是构造一个与谓词结果相反的一元函数对象。
not2是构造一个与谓词结果相反的二元函数对象。
头文件:#include
2.程序测试
//打印
struct MyPrint02 {
void operator()(int v) {
cout << v << " ";
}
};
struct MyCompare : public binary_function<int, int, bool> {
bool operator()(int v1, int v2) const {
return v1 > v2;
}
};
struct MyGreater5 : public binary_function<int, int, bool> {
bool operator()(int v, int val) const {
cout << "v:" << v << " val:" << val << endl;
return v > val;
}
};
//一元谓词绑定,unary_function
struct MyGreater6:public unary_function<int,bool> {
bool operator()(int val)const {
//cout << "vvvv: " << val << endl;
return val > 50;
}
};
void test02() {
vector<int> v;
for (int i = 0; i < 10; i++) {
//产生10个100以内的随机数
v.push_back(rand() % 100);
}
cout << "not2 functional Test:" << endl;
for_each(v.begin(), v.end(), MyPrint02()); cout << endl;
//MyCompare本来是从大到小排列的,加上not就是从小到大了;
sort(v.begin(), v.end(), not2(MyCompare()));
for_each(v.begin(), v.end(), MyPrint02()); cout << endl;
//not1 not2
//如果对二元谓词取反,用not2
//如果对一元谓词取反,用not1
auto i = find_if(v.begin(), v.end(), not1(MyGreater6()));
if (i == v.end()) {
cout << "greater 没有找到" << endl;
}
else {
cout << "wwwwwww: " << *i << endl;
}
//bind2nd与not2结合使用
cout << "bind2nd与not2 测试: " << endl;
vector<int>::iterator it;
it = find_if(v.begin(), v.end(), not1(bind2nd(MyGreater5(), 10)));
if (it == v.end()) {
cout << "没有找到" << endl;
}
else {
cout << *it << endl;
}
}
测试结果:
三.ptr_fun使用
1.简介
ptr_fun将普通函数是配成函数对象,这样就可以绑定参数了。
2.程序测试
如果打印容器中的值,
void MyPrint03(int v,int val) {
cout << "v: " << v << " val: " << val << endl;
cout << "PLus: " << v + val << endl;
}
//ptr_fun测试
void test03() {
vector<int> v;
for (int i = 0; i < 5; i++) {
v.push_back(i);
}
/*MyPrint03(int v)是一个函数,正常情况下无法绑定参数
ptr_fun将普通函数是配成函数对象,这样就可以绑定参数了
MyPrint03(int v,int val)
*/
cout << "ptr_fun Test" << endl;
for_each(v.begin(), v.end(), bind2nd(ptr_fun(MyPrint03),10));
}
}
四.men_fun和men_fun_ref的使用
1.简介
如在使用for_each迭代打印时想调用成员函数,这时候就可以用到mem_fun和mem_fun_ref了。
如果存放的是对象指针 ,使用 mem_fun
如果使用的是对象,使用 mem_fun_ref
2.程序测试:
声明一个类,其中包括了成员函数show()
class Person {
public:
Person(int age, int id) :age(age), id(id) {}
void show() {
cout << "age:" << age << " id:" << id << " aaa" << endl;
}
public:
int age;
int id;
};
欲通过for_each()函数调用类中的成员函数实现打印,
当容器中中存放的是对象时,使用men_fun_ref(&类名::函数名)
for_each(v.begin(), v.end(), mem_fun_ref(&类名::函数名));
//成员函数适配器 mem_fun mem_fun_ref
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);
cout << "mem_fun_ref test..." << endl;
//格式: &类名::函数名
for_each(v.begin(), v.end(), mem_fun_ref(&Person::show));
}
而如果容器中存放的是对象指针时,就要用到men_fun了。
vector<Person*> v1;
v1.push_back(&p1);
v1.push_back(&p2);
v1.push_back(&p3);
cout << "mem_fun test..." << endl;
for_each(v1.begin(), v1.end(), mem_fun(&Person::show));