sort(vec.begin(), vec.end(), greater<int>()); //从大到小对vector进行排序find_if(vec.begin(), vec.end(), bind1st(greater<int>(), 70));find_if(vec.begin(), vec.end(), bind2nd(less<int>(), 70));
两个绑定器分别提前绑定了一个参数,使得二元函数对象+绑定器转换为一元函数对象:
operator()(const T &val)greater a > b ====> bind1st(greater<int>(), 70) ====> 70 > blessa < b ====> bind2nd(less<int>(),70) ====> a < 70
下面给出bind1st
绑定过程图,二元函数对象绑定了第一个数为70
,变为一元函数对象,传递给find_if
泛型算法,此时find_if
所实现的功能就是:找出有序降序数组中第一个小于70
的数,所以find_if
返回指向65
元素的迭代器:
file:///Users/guochen/Notes/docs/media/16656563650484/16657214749366.jpg

文章插图
以上就是绑定器的概念 。因此需要绑定器的原因就很明显了,绑定器可以返回一个转换后的某元函数对象,用于匹配泛型算法 。
根据上面的理解,接下来实现一下
bind1st
,代码实现如下:/*可以看到 自己实现的绑定器本质上也是个函数对象 调用operator()进行绑定*/template<typename Compare, typename T>class _mybind1st {public:_mybind1st(Compare comp, T first) : _comp(comp), _val(first) {}bool operator()(const T &second) {return _comp(_val, second);}private:Compare _comp;T _val;};/*实现bind1st 函数模板*///直接使用函数模板,好处是可以进行类型推演template<typename Compare, typename T>_mybind1st<Compare, T> mybind1st(Compare comp, const T &val) { //绑定器返回值_mybind1st为一元函数对象return _mybind1st<Compare, T>(comp, val);}
上述代码中mybind1st
绑定器第一个参数Compare comp
是要绑定的二元函数对象,第二个参数val
是在原有函数对象上绑定的值,最后绑定器调用_mybind1st
模板函数对象的小括号运算符重载并返回该一元匿名函数对象,可以看到_mybind1st
小括号运算符重载中已将绑定器mybind1st
第二个参数val
传递给了原本的二元函数对象Compare comp
,因此原本绑定器接收的二元函数对象只需要处理第二个参数 。所以绑定器返回的函数对象_mybind1st
其实是在原本的函数对象上套了一层参数的新的函数对象,阅读上面的代码实现,就可更深刻的理解bind1st
的底层原理 。与此同时,不难写出
bind2nd
的实现,顾名思义该绑定器是对第二个参数进行绑定,不过多赘述,贴出实现代码:template<typename Compare, typename T>class _mybind2nd {public:_mybind2nd(Compare comp, T second) : _comp(comp), _val(second) {}bool operator()(const T &first) {return _comp(first, _val);}private:Compare _comp;T _val;};template<typename Compare, typename T>_mybind2nd<Compare, T> mybind2nd(Compare comp, const T &val) {return _mybind2nd<Compare, T>(comp, val);}
根据上文,我们清楚了解到泛型算法find_if
第三个参数接收一元函数对象,且该泛型算法功能是寻找第一个符合某条件的元素,我们对其补充实现,代码贴出:/** * 自己实现了find_if后发现其实绑定器返回的就是绑定后的函数对象 * 使用绑定器的目的:就是将原本某元的函数对象转化为另一个元的函数对象 * 说白了,绑定器还是对函数对象的一个应用 **/template<typename Iterator, typename Compare>Iterator my_find_if(Iterator first, Iterator last, Compare comp) {for(; first != last; ++first) {if(comp(*first)) { //调用comp的小括号运算符重载 一元函数对象 comp.operator()(*first)return first;}}return last;}
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 路由器每天晚上都关掉好不好路由器每天晚上都关掉会怎么样
- 路由器放在墙边还是角落 路由器放在哪里比较好
- 路由器辐射是手机的多少倍 路由器辐射怎么减少
- 2023年9月22日是安机器的黄道吉日吗 2023年农历八月初八宜安机器吗
- 2023年9月22日适合安装机器吗 2023年9月22日安装机器好吗
- 2023年9月23日是安机器吉日吗 2023年农历八月初九安机器吉日
- 2023年9月23日是安装机器吉日吗 2023年9月23日安装机器行吗
- .net core Blazor+自定义日志提供器实现实时日志查看器
- 干粉灭火器如何使用
- c类火灾用什么灭火器