函数适配器
1)函数适配器
2)常用函数适配器
标准库提供一组函数适配器,用来特殊化或者扩展一元和二元函数对象。常用适配器是:
1绑定器(binder): binder通过把二元函数对象的一个实参绑定到一个特殊的值上,将其转换成一元函数对象。C++标准库提供两种预定义的binder适配器:bind1st和bind2nd,前者把值绑定到二元函数对象的第一个实参上,后者绑定在第二个实参上。
2取反器(negator) : negator是一个将函数对象的值翻转的函数适配器。标准库提供两个预定义的ngeator适配器:not1翻转一元预定义函数对象的真值,而not2翻转二元谓词函数的真值。
常用函数适配器列表如下:
bind1st(op, value)
bind2nd(op, value)
not1(op)
not2(op)
mem_fun_ref(op)
mem_fun(op)
ptr_fun(op)
3)常用函数适配器案例
#include"vector" #include"algorithm" #include"string" #include"functional" #include"iostream" using namespace std; class dayu { public: dayu(int i) { num = i; } bool operator()(int &n) { if (n > num) { return true; } else { return false; } } private: int num; }; int main01() { vector<int>v1(15); for (int i = 0; i < 15; i++) { v1[i] = rand() %100; } for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) { cout << *it << " ";//41 67 34 0 69 24 78 58 62 64 5 45 81 27 61 } cout << endl; //求出5的个数;count /*template<class _InIt, class _Ty> inline typename iterator_traits<_InIt>::difference_type count(_InIt _First, _InIt _Last, const _Ty& _Val) { // count elements that match _Val _DEBUG_RANGE(_First, _Last); return (_Count_np(_Unchecked(_First), _Unchecked(_Last), _Val)); }*/ int num1 = count(v1.begin(),v1.end(),5); cout << "5的个数num1=: " << num1 << endl;//1 //////////////求出大于50的数的个数////////////////// //通过谓词的方式求解 /*template<class _InIt, class _Pr> inline typename iterator_traits<_InIt>::difference_type count_if(_InIt _First, _InIt _Last, _Pr _Pred) { // count elements satisfying _Pred _DEBUG_RANGE(_First, _Last); _DEBUG_POINTER(_Pred); return (_Count_if(_Unchecked(_First), _Unchecked(_Last), _Pred)); }*/ int num2 = count_if(v1.begin(),v1.end(),dayu(50)); cout << "dayu(50)num2=: " << num2 << endl;//8 //通过函数适配器的方式求解 /* // TEMPLATE STRUCT greater template<class _Ty = void> struct greater : public binary_function<_Ty, _Ty, bool> { // functor for operator> bool operator()(const _Ty& _Left, const _Ty& _Right) const { // apply operator> to operands return (_Left > _Right); } }; */ int num3 = count_if(v1.begin(),v1.end(),bind2nd(greater<int>(),50));//令_Right=50; cout << "大于50的个数num3= " << num3 << endl; //////////////////求奇偶数的个数(能否被2整除)/////////////////////// /* // TEMPLATE STRUCT modulus template<class _Ty = void> struct modulus : public binary_function<_Ty, _Ty, _Ty> { // functor for operator% _Ty operator()(const _Ty& _Left, const _Ty& _Right) const { // apply operator% to operands return (_Left % _Right); } }; */ //左参数来自容器,右参数来自自定义 int num4 = count_if(v1.begin(), v1.end(),bind2nd(modulus<int>(),2)); cout << "奇数个数num4= " << num4 << endl; //8 int num5 = count_if(v1.begin(), v1.end(), not1(bind2nd(modulus<int>(), 2))); cout << "偶数个数num5= " << num5 << endl; //7 return 0; } /////////////////////成员函数适配器/////////////// class Student {public: string num; string name; public: Student(string num,string name) { this->num = num; this->name = name; } bool show() { cout << num << ":"<<name << endl; return true; } }; int main02() { //mem_fun_ref 当集合是基于对象的 Student s1("1001","liubang"); Student s2("1002", "xiangyu"); vector<Student> v; v.push_back(s1); v.push_back(s2); for_each(v.begin(),v.end(),mem_fun_ref(&Student::show)); //mem_fun 当集合是基于对象指针的 Student *ps1=new Student("1001", "liubang"); Student *ps2=new Student("1002", "xiangyu"); vector<Student*> pv; pv.push_back(ps1); pv.push_back(ps2); for_each(pv.begin(), pv.end(), mem_fun(&Student::show)); return 0; } ///////////////////////普通函数适配器的基本用法(ptr_fun)////////////// /*template<class _Arg, class _Result> inline pointer_to_unary_function<_Arg, _Result, _Result (__cdecl *)(_Arg)> ptr_fun(_Result (__cdecl *_Left)(_Arg)) { // return pointer_to_unary_function functor adapter return (pointer_to_unary_function<_Arg, _Result, _Result (__cdecl *)(_Arg)>(_Left)); */ bool f(int x) { return x > 3; } bool g(int x,int y) { return x > y; } int main03() { int a[] = {0,1,2,3,4,5,6,7,8,9}; int nsize = sizeof(a) / sizeof(int); int numf3 = count_if(a, a + nsize, f); cout << "numf>3: "<<numf3 << endl; //6 对一个参数的普通函数而言,ptr_fun无太大优势; int numf4 = count_if(a, a + nsize, ptr_fun(f)); cout << "numptr_fun(f): " << numf4 << endl; //6 int numg = count_if(a, a + nsize, bind2nd(ptr_fun(g),5)); cout << "numptr_fun(g): " << numg << endl; //4 return 0; } int main() { //main01(); //main02(); main03(); system("pause"); return 0; }
//综合案例1
//////////编程求圆和长方形的面积//////////////////// #include"iostream" #include"vector" #include"algorithm" #include"functional" using namespace std; class Shape { public: virtual bool showarea() = 0; }; class Circle:public Shape { private: float r; public: Circle(float r) { this->r = r; } bool showarea() { cout << "Area of The Circle is: " << 3.14*r*r << endl; return true; } }; class Rectangle :public Shape { private: float length; float width; public: Rectangle(float length,float width) { this->length = length; this->width = width; } bool showarea() { cout << "Area of The Rectangle is: " << length*width << endl; return true; } }; class Shapemanager {private: vector<Shape*>v;//多态,所以采用基类指针 public: bool add(Shape* s) { v.push_back(s);//添加形状指针; return true; } bool showEACHarea() { for_each(v.begin(),v.end(),mem_fun(&Shape::showarea)); return true; } }; int main() { Shapemanager spm; Shape *obj1 = new Circle(5); Shape *obj2 = new Rectangle(5,15); spm.add(obj1); spm.add(obj2); spm.showEACHarea();//78.5 , 75 system("pause"); return 0; }
//综合案例2
//假设学生对象的集合的索引从0开始,依次增1, //要求不改变学生成绩集合中学生对象的顺序,依据成绩升序输出索引 #include"iostream" #include"vector" #include"algorithm" #include"functional" #include"string " #include"iterator" using namespace std; class Student { public: string num; int grade; public: Student( string num,int grade) { this->num = num; this->grade = grade; } }; class Studmanager { private: vector<Student> &v;//学生集合对象de引用 public: Studmanager(vector<Student> &v): v(v){ } bool operator()(int a,int b)//a,b表示学生对象的序号 { return v[a].grade < v.at(b).grade;//按成绩从小到大排序 } }; int main() { Student s1("1001",70); Student s2("1002", 76); Student s3("1003", 90); Student s4("1004", 87); vector<Student>vStudent; vStudent.push_back(s1); vStudent.push_back(s2); vStudent.push_back(s3); vStudent.push_back(s4); vector<int>v1; v1.push_back(0); v1.push_back(1); v1.push_back(2); v1.push_back(3); sort(v1.begin(), v1.end(), Studmanager(vStudent));//序号按照成绩的大小排序 copy(v1.begin(),v1.end(),ostream_iterator<int>(cout," "));//0132 system("pause"); return 0; }