知识点3:内建函数对象
stl提供了一下标准的函数对象(算数类函数对象,关系运算类函数对象,逻辑运算类仿函数)
6 个算数类函数对象,除了 negate 是一元运算,其他都是二元运算。
template<class T> T plus<T>//加法仿函数
template<class T> T minus<T>//减法仿函数
template<class T> T multiplies<T>//乘法仿函数
template<class T> T divides<T>//除法仿函数
template<class T> T modulus<T>//取模仿函数
template<class T> T negate<T>//取反仿函数
6 个关系运算类函数对象,每一种都是二元运算。
template<class T> bool equal_to<T>//等于
template<class T> bool not_equal_to<T>//不等于
template<class T> bool greater<T>//大于
template<class T> bool greater_equal<T>//大于等于
template<class T> bool less<T>//小于
template<class T> bool less_equal<T>//小于等于
3个逻辑运算类运算函数,not 为一元运算,其余为二元运算。
template<class T> bool logical_and<T>//逻辑与
template<class T> bool logical_or<T>//逻辑或
template<class T> bool logical_not<T>//逻辑非
案例:
#include <iostream>
#include <set>
using namespace std;
class Sum
{
public:
int operator ()(int a,int b){
return a+b;
}
};
void printset( set<int,greater<int>> &s){
set<int>::const_iterator it=s.begin();
for(;it!=s.end();it++){
cout<<*it<<" ";
}
cout<<endl;
}
int main(int argc, char *argv[])
{
//template<class T> T plus<T>//加法仿函数
plus<int> p;
cout<<"p是一个内建函数对象,和="<<p(100,66)<<endl;
Sum s;
cout<<"s是一个自定义的函数对象,和="<<s(100,66)<<endl;
//取反
negate<int >n;
cout<<"n是一个内建函数对象,取反="<<n(1)<<endl;
//判断两者是否相等
equal_to<int> e;
if(e(100,200))
cout<<"两者相等"<<endl;
else
cout<<"两者不等"<<endl;
//使用greater实现set的降序
set<int,greater<int>> obj;
obj.insert(2);
obj.insert(1);
obj.insert(9);
obj.insert(7);
obj.insert(5);
printset(obj);
//逻辑与
logical_and<bool> l;
if(l(true, false))
cout<<"两者都为真"<<endl;
else
cout<<"两者至少一假"<<endl;
return 0;
}
知识点4:适配器
适配器作用:
给仿函数或者算法提供更多接口的。
适配器使用:
bind1st():将100给到printvector函数的第一个参数
bind1st(ptr_fun(printvector),100)
bind2nd():将100给到printvector函数的第二个参数
bind2nd(ptr_fun(printvector),100)
1、普通函数适配器(遍历vector容器时给每个元素+100再输出)
1.1for_each使用:
1.2适配器使用:
2、函数对象适配器(遍历vector容器时给每个元素+100再输出)
3、成员函数适配器
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Person
{
private:
int age;
string name;
public:
Person() {}
Person(int age,string name) {
this->age=age;
this->name=name;
}
void printv(){
cout<<name<<" "<<age<<endl;
}
#if 0
void printv(string addr){
cout<<addr<<name<<" "<<age<<endl;
}
#endif
};
int main(int argc, char *argv[])
{
vector<Person> v;
v.push_back(Person(20,"小明"));
v.push_back(Person(21,"小宏"));
v.push_back(Person(22,"小张"));
v.push_back(Person(23,"小可爱"));
v.push_back(Person(24,"小邋遢"));
for_each(v.begin(),v.end(),mem_fun_ref(&Person::printv));
//for_each(v.begin(),v.end(),bind2nd(mem_fun_ref(&Person::printv),"北京"));
vector<Person *> v1;
Person p1(20,"小明");
Person p2(21,"小宏");
Person p3(22,"小张");
Person p4(23,"小可爱");
Person p5(24,"小邋遢");
v1.push_back(&p2);
v1.push_back(&p3);
v1.push_back(&p4);
v1.push_back(&p5);
v1.push_back(&p1);
for_each(v1.begin(),v1.end(),mem_fun(&Person::printv));
return 0;
}
4、取反适配器
not1:一元取反
not2:二元取反
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void printv(int num1,int num2){
if(num1>num2)
cout<<num1<<endl;
}
int main(int argc, char *argv[])
{
vector<int> v;
v.push_back(10);
v.push_back(30);
v.push_back(110);
v.push_back(10);
v.push_back(10);
//一元取反(拿到的是第一个小于100的值)
vector<int>::iterator it= find_if(v.begin(),v.end(),not1(bind2nd(greater<int>(),100)));
if(it !=v.end()){
cout<<*it<<endl;
}
cout<<"-------------"<<endl;
vector<int> v1;
v1.push_back(10);
v1.push_back(30);
v1.push_back(110);
v1.push_back(20);
v1.push_back(40);
sort(v1.begin(),v1.end());
//[](int num){cout<<num<<endl;}匿名函数:函数名[] 参数类型及参数 () 函数体{}
for_each(v1.begin(),v1.end(),[](int num){cout<<num<<endl;});
cout<<"-------------"<<endl;
//二元取反
sort(v1.begin(), v1.end(), not2(less<int>()));
for_each(v1.begin(),v1.end(),[](int num){cout<<num<<endl;});
return 0;
}