头文件:functional 系统仿函数和适配器头文件
函数对象适配器是完成一些配接工作,这些配接包括绑定(bind),否定(negate),以及对一般函数或成员函数的修饰,使其成为函数对象。
绑定器:
bind1st 将参数绑定为二元函数对象的第一个参数。 操作的可调用对象,必须是仿函数
bind2nd 将参数绑定为二元函数对象的第二个参数。 操作的可调用对象,必须是仿函数
bind 将参数绑定为n元函数对象的,第n个参数。 操作的只要是可调用对象即可
求反器:
not1 对一元函数对象取反 操作的可调用对象,必须是仿函数
not2 对二元函数对象取反 操作的可调用对象,必须是仿函数
成员函数适配器:
mem_fun 把成员函数转成仿函数 容器里存的是对象指针
mem_fun_ref 修饰成员函数 容器里存的是对象)
bind1st绑定到第一个参数
bind2nd 绑定到第二个参数
注意:这个两个函数只能 用来绑定仿函数,普通函数不行
自定义的仿函数,还必须从系统定义的一个类继承
一个参数的仿函数从:unary_function
二个参数的仿函数从:binary_function
1、bind2nd和bind1nd的代码实现
struct CTest :public binary_function<int, int, void>
{
void operator()(int i, int val) const
{
cout << i << " + " << val << " = " << i + val << endl;
}
};
void obj3()
{
vector<int> v = { 9,8,7,6,5,1,2,3,4 };
//bind2nd和bind1nd过程一样
for_each(v.begin(), v.end(), bind2nd(CTest(), 10));
//for_each(v.begin(), v.end(), bind1st(CTest(),10));
}
2、bind也是绑定参数,只要是可调用对象,都可以绑定,不在局限于仿函数(函数对象)
std::bind返回一个基于Func的函数对象,其参数被绑定到Args上。 f的参数要么被绑定到值,要么被 绑定到placeholders(占位符,如_1, _2, …, _n)。
参数:
Func:一个可调用对象(可以是函数对象、函数指针、函数引用、成员函数指针、数据成员指
针…),它的参数将被绑定到args上。
Args:绑定参数列表,参数会被值或占位符替换,其长度必须与f接收的参数个数一致。
使用2种:
改变参数个数 和 改变行参顺序。
#include
#include
#include
#include
using namespace std;
bool compare(int a, int b)
{
return a > b;
}
void show(int a, int b, int c)
{
cout << a << "++++" << b << "++++" << c << endl;
}
int main()
{
vector<int> A = { 1,2,3,4,5,6,7,8,9,10 };
//统计比0大的数的个数
auto x=count_if(A.begin(), A.end(), std::bind(compare,std::placeholders::_1,0));
cout << x << endl;
//改变位置
//auto自动推到类型 返回值是与函数类型一致
auto ss = std::bind(show, std::placeholders::_2, std::placeholders::_1, 0);
//std::placeholders::_2, std::placeholders::_1为只不一样会将参数1和二的位置交换
ss(1, 2, 3);
system("pause");
return 0;
}
mem_fun
把类的成员函数转成仿函数
class Person
{
public:
Person(int age, int id) :_age(age), _id(id) {}
void show()
{
cout << "id: " << _id << "age: " << _age << endl;
}
private:
int _age; int _id;
};
void fun_cref()
{
Person p1(1, 2), p2(3, 4), p3(5, 6);
vector< Person*> v = { &p1,&p2,&p3 };
for_each(v.begin(), v.end(), mem_fun(&Person::show));
}
mem_fun_ref
同上,把类的成员函数转成仿函数
class Person
{
public:
Person(int age, int id) :_age(age), _id(id) {}
void show()
{
cout << "id: " << _id << "age: " << _age << endl;
}
private:
int _age;
int _id;
};
void fun_cref()
{
Person p1(1, 2), p2(3, 4), p3(5, 6);
vector< Person> v = { p1,p2,p3 };
for_each(v.begin(), v.end(), mem_fun_ref(&Person::show));
}
两者区别
当容器中存的是对象时使用mem_fun_ref
存放的是对象的指针时使用mem_fun