此时要寻找vector
中第一个小于70
的数,就可以这样写:
auto it = my_find_if(vec.begin(), vec.end(), mybind1st(greater<int>(), 70));cout << *it << endl; //打印vec中第一个小于70的数值
以上,围绕bind1st
、bind2nd
以及函数对象等,展开讨论了绑定器bind1st
、bind2nd
的实现原理,但是同时我们也发现其缺点,就是只能对二元函数对象进行绑定转换,让其转换为一元函数对象,那如果遇到很多元的函数对象,我们还得一个一个自己去实现吗?所以将boost库的boost::bind
引入到了C++11标准库中,接下来我们介绍C++11的绑定器std::bind
,它是对上述两种绑定器的泛化 。支持任意函数对象(其实标准库中最多支持29
元函数对象,不过这也足够使用了) 。
补充:上面都是以函数对象为例,作为绑定器第一个参数传递,其实第一个参数可以是函数对象、成员函数、也可以是普通函数 。总结:绑定器本身是函数模板,绑定器第一个参数可能是普通函数、成员函数或函数对象等,返回的一定是函数对象 。还有就是这两个绑定器在
C++17
中已移除,因此仅用于学习和理解绑定器,也方便我们对C++11引入的bind
的学习 。至于当前这两个绑定器如何实现对类成员函数的绑定等等我们也没必要去寻找答案了(我一开始也在努力寻找如何使用这两个绑定器去绑定类成员函数,但是发现bind
可以很轻松地做到,当然如果大家知道怎么使用bind1st
和bind2nd
绑定类成员函数,也可以评论告知我,感谢~) 。C++11 bind通用绑定器(函数适配器)我们可将
bind
函数看作是一个通用的函数适配器,它接受一个可调用函数对象,生成一个新的可调用函数对象来“适应”原对象的参数列表 。bind相比于bind1st和bind2nd,实现了“动态生成新的函数”的功能 。简言之,可通过bind
函数修改原函数并生成一个可以被调用的对象,类似于函数的重载,但是我们又不需要去重新写一个函数,用bind
函数就可以实现 。相信在上面讲bind1st和bind2nd时,大家对这些关于绑定器(函数适配器)的概念已经有所认知,我们直接看看如何用的吧 。绑定一个普通函数和函数指针
#include <iostream>#include <functional>using namespace std;using namespace placeholders;int fun(int a, int b, int c, int d, int e) {return a + b - c + d - e;}int main() {int x = 1, y = 2, z = 3;auto g = bind(fun, x, y, _2, z, _1); //第一个参数&可省略 但最好写成&funcout << g(11, 22) << endl; // fun(1, 2, 22, 3, 11) => 1+2-22+3-11// cout << bind(fun, x, y, _2, z, _1)(11, 22) << endl; //等价}
g
是有两个参数的二元函数对象,其两个参数分别用占位符placeholders::_2
和placeholders::_1
表示,_2
代表二元函数对象的第二个参数22
,_1
代表二元函数对象的第一个参数11
。这个新的可调用对象将它自己的参数作为第三个和第五个传递给fun,fun函数的第一个、第二个第四个参数分别被绑定到给定的值x
、y
、z
上 。绑定一个类的静态成员函数与绑定全局函数没有任何区别,这里不做说明,可参考文章:[ bind绑定器使用方法 ],该文章中bind详细用法中描述了对静态成员方法的使用 。绑定一个类成员函数
绑定器绑定一个成员函数时,我们知道非静态成员函数第一个参数隐藏了一个
经验总结扩展阅读
- 路由器每天晚上都关掉好不好路由器每天晚上都关掉会怎么样
- 路由器放在墙边还是角落 路由器放在哪里比较好
- 路由器辐射是手机的多少倍 路由器辐射怎么减少
- 2023年9月22日是安机器的黄道吉日吗 2023年农历八月初八宜安机器吗
- 2023年9月22日适合安装机器吗 2023年9月22日安装机器好吗
- 2023年9月23日是安机器吉日吗 2023年农历八月初九安机器吉日
- 2023年9月23日是安装机器吉日吗 2023年9月23日安装机器行吗
- .net core Blazor+自定义日志提供器实现实时日志查看器
- 干粉灭火器如何使用
- c类火灾用什么灭火器