先来看一个小程序:
bool check(int elem);
vecot<int>v; ...
pos=find_if(v.begin(),v.end(),not1(check))竟然出错,查找资料之后,发现,原来原因如下:
ptr_fun做的唯一的事是使一些typedef有效,从而将函数转化为函数对象(Returns a function object that encapsulates function f)( 仿函数类的operator()所带的参数的类型和它的返回类型。对于binary_function,你要指定三个类型:你的operator的第一个和第二个参数的类型,和你的operator地返回类型; 而这两个基类 typedef 了argument_type、first_argument_type、second_argument_type和result_type 这几种类型 )。就是这样。not1需要这些typedef,这就是为什么可以把not1应用于ptr_fun,但不能直接对check应用not1。因为是低级的函数指针,check缺乏not1需要的typedef。
not1不是STL中唯一有那些要求的组件。四个标准函数适配器(not1、not2、bind1st和bind2nd)都需要存在某些typedef
c++标准程序库提供的一些结构如下:
template<typename Arg,typename Result> struct unary_function{ typedef Arg argument_type; typedef Result result_type; }; template<typename Arg1,typename Arg2,typename Result> struct binary_function{ typedef Arg1 first_argument_type; typedef Arg2 second_argument_type; typedef Result result_type; };
STL中函数适配器的作用是把普通函数、函数指针转化为函数对象。STL中有四个标准适配器(not1、not2、bind1st、bind2nd)和两个函数适配器mem_fun和mem_fun_refnot2也是一样的道理,not2是用于一个含有两个参数返回值为bool的函数
#include<iostream> #include<string> #include<vector> #include<functional> #include<algorithm> using namespace std; bool check(int a){ if(a%2==0){ return true; }else{ return false; } } int main(){ int a[]={1,2,3,4,5,6,7,8,9,10}; vector<int>v(a,a+10); vector<int>::iterator it=find_if(v.begin(),v.end(),not1(ptr_fun(check))); cout<<*it<<endl; system("pause"); return 0; }
mem_fun_ref和men_fun是针对成员函数而设计的函数适配器。mem_fun_ref的作用和用法跟mem_fun一样,唯一的不同就是:当容器中存放的是对象的时候用mem_fun_ref,当容器中存放的是对象的指针的时候用mem_fun。
先看看mem_fun_ref的应用:
#include<iostream> using namespace std; #include<functional> #include<algorithm> #include<bitset> #include<vector> class A { public: int Fun() { cout<<"Fun"<<endl; return 0; } }; void main() { vector<A> vectA; for(int i=1;i<3;i++) { A a; vectA.push_back(a); } for_each(vectA.begin(),vectA.end(),mem_fun_ref(&A::Fun));// mem_fun_ref的作用和用法跟mem_fun一样,唯一的不同就是:当容器中存放的是对象实体的时候用mem_fun_ref,当容器中存放的是对象的指针的时候用mem_fun。 }
再看看mem_fun的应用:
#include<iostream> using namespace std; #include<functional> #include<algorithm> #include<bitset> #include<vector> class A { public: int Fun() { cout<<"Fun"<<endl; return 0; } }; void main() { vector<A*> vectA; for(int i=1;i<3;i++) { A * a=new A; vectA.push_back(a); } for_each(vectA.begin(),vectA.end(),mem_fun(&A::Fun));// mem_fun_ref的作用和用法跟mem_fun一样,唯一的不同就是:当容器中存放的是对象实体的时候用mem_fun_ref,当容器中存放的是对象的指针的时候用mem_fun。 }