碎碎念:
建议先看下上面这篇文章,可以高屋建筑的把握C++中所有关于适配器的内容,达到一种感性的认识。讲解还是从使用场合和常见的使用方法。
使用场合:
从两个角度说,为什么要学习C++的函数适配器bind()函数。
考虑一种情况,有一个数组,一个需求是 计算出容器中小于50的数的个数。
很多人立即想到有一个算法是count_if(beg,end,pred);
beg和end是容器的范围,而pred可以是一个函数。不过对于我们这个需求,这个函数有点特殊,它需要接受两个参数,第一个参数就是容器中的元素,第二个参数是50。这就有两个问题出现了,
第一个问题: count_if 所要求的pred函数必须只能接受一个参数。而我们的需求需要接受两个。
第二个问题: 如果程序中我们的需求变了呢?比如我们在后面的程序要计算的是容器中小于40的数的个数呢?我们当然可以编写很多个函数来解决这个问题,但这不符合软件工程的思想。
因此:我们C++11引入了bind这个函数适配器,它接受一个函数,生成一个新的函数来改变原来函数的参数列表。比如减少原来函数的参数个数,或者顺序。使得它满足新的需求。
使用方法:
1.头文件和命名空间
#include<functional>
using namespace std::placeholders; //主要为了后面的占位符
2.举例
bind的使用方法:
bind(函数名,arg_list);
arglist 是一个被逗号分隔的原来函数的参数列表,里面可包含占位符.n代表新的函数里的参数的位置。 看下简单的例子,就会很快就懂了。
1.改造一个函数:(结果在后面的注释里面)
double
如果没看懂,就返回去仔细看注释,再看一遍,一定会懂哒!
总结一下:
1.bind 的参数列表中有几个 _n,新生成的函数里面就有几个参数。
2.bind的一个作用是可以改变参数的顺序和参数的个数。
3.解决我们开头的问题
考虑一种情况,有一个数组,一个需求是 计算出容器中小于50的数的个数。很多人立即想到有一个算法是count_if(beg,end,pred);
深入一点:我们前面说bind的形式是: bind(函数名,arg_list);
其实bind改造的不一定是函数,而是可调用对象。:包括函数,函数指针,函数对象,lambda表达式。
这里我们采用改造标准库函数对象的方式解决这个问题。
vector<int> v{15,37,94,50,73,58,28,90};
auto fn=bind(less<int>(),_1,50);
cout<<coutif(v.begin(),v.end(),fn_);//3
打完收工。
看完这篇文章,你可以延伸学习的有,函数对象,lambda表达式。加油。
勿在浮沙筑高层。共勉!