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;}
此时要寻找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
的学习 。至于当前这两个绑定器如何实现对类成员函数的绑定等等我们也没必要去寻找答案了(我一开始也在努力寻找如何使用这两个绑定器去绑定类成员函数 , 但是发现
推荐阅读
- .net core Blazor+自定义日志提供器实现实时日志查看器
- 小样本利器4. 正则化+数据增强 Mixup Family代码实现
- 学习ASP.NET Core Blazor编程系列九——服务器端校验
- nginx 客户端返回499的错误码
- 三、Go环境安装
- 100版本dnf如何给武器镶嵌徽章(dnf如何在装备上镶嵌徽章)
- oppoa93参数配置详情_oppoa93参数配置详情处理器
- 崩坏3武器索尔之锤强度如何
- 天玑1100相当于骁龙多少处理器_天玑1100相当于骁龙什么水平
- 我的世界暗物质武器怎么做(我的世界暗物质套怎么合成)