C++:函数对象,STL提供的函数对象,函数适配器详解
C++:函数对象,STL提供的函数对象,函数适配器详解,博智网带你了解详细信息 。
目录
- 1 函数对象
- 2 STL提供的函数对象
- 3 函数适配器
- 总结
1 函数对象1.函数对象是行为类似函数的对象 。一个类对象,表现出一个函数的特征,即通过对象名+(参数列表)的方式使用一个类对象 。
2.使用STL中提供的或自定义的迭代器和**函数对象,**配合STL的算法,组合出各种各样的功能 。
3.通过函数对象而不使用函数指针,可以增加通用性,提高效率 。
4.函数对象概念:泛化的函数





①找出第一个大于40的数,注意用数组和vector都可以
#include <iostream>#include <algorithm>#include <functional>#include <vector>using namespace std;int main(){int a[] = { 30, 40, 50, 90, 20, 10 };const int N = sizeof(a) / sizeof(int);int *c = find_if(a, a + N, bind2nd(greater<int>(), 40));cout << *c << endl;return 0;}
一般使用数组初始化向量vector,后续操作更方便
int main(){int a[] = { 30, 40, 50, 90, 20, 10 };const int N = sizeof(a) / sizeof(int);vector<int> v (a, a + N); //用数组初始化vectorvector<int>::iterator p = find_if (v.begin(), v.end(), bind2nd(greater<int>(), 40) );if (p == v.end())cout << "找不到" << endl;elsecout << *p << endl;return 0;}
find_if算法在STL中的原型声明为:template<class InputIterator, class UnaryPredicate>InputIterator find_if(InputIterator first, InputIterator last, UnaryPredicate pred);它的功能是查找数组[first, last)区间中第一个pred(x)为真的元素 。InputIterator、UnaryPredicate是用概念来做模板参数名
②利用prt_fun、not1、not2产生组合适配器
#include <iostream>#include <functional>#include <algorithm>#include <vector>using namespace std;int g(int x, int y) { //实现类似greater的功能return x > y;}int main(){int a[] = { 30, 90, 10, 23, 432, 656, 7, 78 };const int N = sizeof(a) / sizeof(int);vector<int> v(a, a + N);auto p1 = find_if(v.begin(), v.end(), bind2nd(ptr_fun(g), 40)); //找第一个大于40的数//ptr_fun将函数指针转换为函数对象,bind2nd将40作为二元函数对象的第二个参数if (p1 == v.end())cout << "no element" << endl;elsecout << *p1 << endl;auto p2 = find_if(v.begin(), v.end(), not1(bind2nd(ptr_fun(g), 15))); //找第一个不大于15的数//not1对一元函数对象取逻辑反,find_if找到第一个令bind2nd取false的值if (p2 == v.end())cout << "no element" << endl;elsecout << *p2 << endl;auto p3 = find_if(v.begin(), v.end(), bind2nd(not2(ptr_fun(g)), 15)); // 找第一个不大于15的数//not2对二元函数取逻辑反if (p3 == v.end())cout << "no element" << endl;elsecout << *p3 << endl;return 0;}
【C++:函数对象,STL提供的函数对象,函数适配器详解】③成员函数适配器,类的成员函数要通过适配器转换为普通函数对象
#include <iostream>#include <vector>#include <functional>#include <algorithm>using namespace std;struct Car{ int id; Car(int id) {this->id = id; } void display() const {cout << "car " << id << endl; }};int main() { vector<Car*> pcars; vector<Car> cars; for (int i = 0; i < 5; i++)pcars.push_back(new Car(i)); //push_back() 在Vector最后添加一个元素(参数为要插入的值) for (int i = 5; i < 10; i++)cars.push_back(Car(i)); cout << "elements in pcars: " << endl; for_each(pcars.begin(), pcars.end(), mem_fun(&Car::display));//for_each算法对每一个迭代器范围中的元素进行函数对象计算 //men_fun适配后函数对象的参数为"对象的指针" cout << endl; for_each(cars.begin(), cars.end(), mem_fun_ref(&Car::display)); //men_fun_ptr适配后函数对象的参数为"对象的引用" cout << endl; for (size_t i = 0; i < pcars.size(); ++i)delete pcars[i]; return 0;}
为什么不能同全局函数一样直接传递函数名而成员函数必须以 &类名::函数名 的方式,因为需要考虑static成员函数的情况 。
mem_fun(member适配为function):将成员函数适配为普通函数对象,适配出来的函数需要对象的指针作为参数 。
men_fun_ref:将成员函数适配为普通函数对象,适配出来的函数需要对象的引用作为参数 。
推荐阅读
- 哪五种函数考虑左右极限
- 课税对象是指哪些
- 连续函数乘以连续函数还连续吗
- 驻点和极值点的区别
- 减法函数是哪个符号
- 二次函数的顶点坐标怎么求
- 二次函数的开口大小取决于什么
- 对应关系怎么判断
- 二元函数偏导数怎么求
- 已婚女人梦见找对象是什么意思
