C++11绑定器bind及function机制( 二 )


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

C++11绑定器bind及function机制

文章插图
以上就是绑定器的概念 。因此需要绑定器的原因就很明显了,绑定器可以返回一个转换后的某元函数对象,用于匹配泛型算法 。
根据上面的理解,接下来实现一下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;}

经验总结扩展阅读