这里介绍仿函数,谓词,内建函数对象,适配器的用法
仿函数
仿函数: 又称函数对象,实际上是重载操作符 () 其中不定义构造和析构函数
只有一个参数是一元仿函数,两个就是二元
EG:
class Func
{
public:
void operator()(int num)
{
static int count = 0;
cout << num << " "<<endl;
count++;
cout << count << endl;
}
};
int main()
{
Func f;
f(11);
f(11);
f(11);
return 0;
}
优点:
①函数对象超越了普通函数的概念,可以在内部保存其状态
比如调用次数
②函数对象可以作为参数调用
假设已定义Myprint print为仿函数的对象
void doPrint (Myprint print,int num)
{
print(num);
}
void test03()
{
doPrint(Myprint(),20);
}
③性能好,通用性强
应用1:谓词
谓词是 普通函数 或返回值为bool类型的仿函数,可作为一个判别式
find_if()方法 头文件为algorithm
find_if(v.begin(),v.end(),谓词(仿函数));
返回值是一个迭代器
EG:
假设我要找一个大于20的数
class Func
{
public:
bool operator()(int num)
{
return num > 20;
}
};
int main()
{
vector<int>v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
vector<int>::iterator pos = find_if(v.begin(), v.end(), Func());
if(pos!=v.end())
cout << *pos << endl;
return 0;
}
应用2:内建函数对象
以我目前的渣渣水平来看,还不如直接用运算符
应用3:适配器
可以将其理解为华为的拓展坞(不知道的可以上某宝看看)
也就是说在原有容器中实现某些原本没有的操作,比如元素相加
此处引用一篇帖子帮助理解
头文件< functional >
一.函数适配器
第一步:绑定数据
bind2nd(仿函数,数据);
第二步:继承类
binary_functional< 参数类型1,参数类型2,返回值 >
第三步:加const修饰operator
class MyPrint:public binary_function<int,int,void>
{
public:
void operator ()(int num,int start)const
{
cout << num + start << endl;
}
};
void test01()//函数适配器
{
vector<int>v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
int num;
cin >> num;
for_each(v.begin(), v.end(), bind2nd(MyPrint(), num));
}
结果:
我输入一个100,通过适配器,实现了容器内所有元素都加100的操作
二.取反适配器
应用:找出大于/小于某个值的数
第一步:取反适配器 not1
第二步:继承类:unary_functional<参数类型,返回值>
第三步:const修饰operator()
上代码:
class Func :public unary_function<int,bool>
{
public:
bool operator()(int val) const
{
if (val > 20)
{
cout << val << endl;
return true;
}
return false;
}
};
void test()
{
vector<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
for_each(v.begin(), v.end(), not1(Func()));
}
三.函数指针适配器
作用:将函数指针适配成函数对象
ptr_fun(函数名);==>将函数指针转换为函数对象(仿函数)
EG:ptr_fun(F1);//将F1转换为函数对象(仿函数),其实也就是 获取了函数F1()的功能 或者说,把普通函数F1()变成了仿函数
步骤基本同函数适配器
上代码:
void MyPrint02(int num,int start)
{
cout << num + start << endl;
}
void test02()//函数指针适配器
{
vector<int>v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
for_each(v.begin(), v.end(), bind2nd(ptr_fun(MyPrint02), 100));
}
四.成员函数适配器
第一步:先定义一个类,类中要有成员函数
第二步:插入自定义数据类型
第三步:遍历:for_each(v.begin(),v.end(),mem_fun_ref(&类名::成员函数名))
如果:容器中存放的是对象指针:用mem_fun
如果存放的是对象实体:用mem_fun_ref
上代码
class myclass
{
public:
myclass(int n)
{
num = n;
}
void print()
{
cout << num << endl;
}
int num;
};
void test03()//成员函数适配器
{
vector<myclass>v;
myclass mc(10);
v.push_back(mc);//插入自定义数据类型
for_each(v.begin(), v.end(), mem_fun_ref(&myclass::print));
}