码迷,mamicode.com
首页 > 其他好文 > 详细

Function Objects Adapter(函数对象适配器)

时间:2015-06-16 14:47:30      阅读:92      评论:0      收藏:0      [点我收藏+]

标签:函数对象   适配器   adapter   

  在讲函数对象适配器之前,让我来看看什么是适配器,广义上讲Adaper就是一种将某一接口转换为另一接口的组件。
比如某电器是欧式插头,你怎么插在国标插座上,最直观的想法就是再买个转接器转一下,没错,这个转接器就是一个Adater。
  如图(生活中的Adapter)
技术分享
  让我来看之前文章提到的求是否是偶数的even函数,先考虑even就是普通的函数,原型为:
   bool even(int x);
   现在如果我们要求一个数是否是奇数,你当然可以写一个判别是否是奇数的函数,那么是否可以重用上面的even函数呢?当然可以,如下:

bool odd(int x) {
        return !even(x);
}

  这也可以看成一个简单的adapter,把原来判别偶数的功能换成了判别奇数,就像上面的插头一样,你可以重换一个插头,也可以买一个转接器,显然后者成本更低,也更灵活。
   下面,再让我们看看之前提到的查找第一个偶数的例子:
   find_if(f,l,even());
  现在我们要查找第一个偶数,同样借鉴上面的想法,我们可以做一个适配器:

template <class Predicate>
class unary_negate {
private:
Predicate pred;
public:
unary_negate(const Predicate& x) : pred(x) {}
bool operator()(const typename Predicate::argument_type& x) const {
    return !pred(x);
  }
};

  可以unary_negate(f)获得一个这样的adapter,但是这样写太麻烦了,我们必须提供函数对象f和类型F,我们可以再包一层:

template <class Predicate>
    inline unary_negate<Predicate> not1(Predicate &pre){
    return unary_negate<Predicate> (pre);
}

  这里利用函数的参数类型推导,那么我们查找奇数就可以写成:find_if(f,l,not1(even()));
  这样我们就通过adater服用了even这个函数对象,而不必重新写新的函数对象。

  让我们再来看一个例子:
  <注:下面例子为了结构清楚,都省略了unary_function和binary_function的继承,实际是有的>

template <class T>  
struct less {  
    bool operator()(const T& x, const T& y) const { return x < y; }  
};

  显然,less是一个小于比较功能的函数对象;
  我们要实现求一个容器中小于某一特定值的元素个数,函数如下:

template <class InputIter, class Predicate, class Size>  
void count_if(InputIter first, InputIter last, Predicate pred, Size& n) {  
    for ( ; first != last; ++first)  
        if (pred(*first))  
            ++n;  
}

  显然这里的pred只有一个参数,上面的less有两个参数,怎么通过adater进行重用呢,让我们来看下面的代码:

template <class Operation>   
class binder2nd{  
public:  
        binder2nd(const Operation& x, const typename Operation::second_argument_type& y) : op(x), value(y) {} 
typename Operation::result_type operator()(const typename Operation::first_argument_type& x) const {  
        return op(x, value);    
}  
protected:  
        Operation op;  
        typename Operation::second_argument_type value;  
};  
template <class Operation, class T>  
inline binder2nd<Operation> bind2nd(const Operation& fn, const T& x) {  
    typedef typename Operation::second_argument_type arg2_type;  
    return binder2nd<Operation>(fn, arg2_type(x));  
}

  那么,我们就可以通过下面调用得到容器中小于88的元素个数:
  count_if(f, l, bind2nd(less_equal(), 88),count);
  本文对Adapter做了简单探讨,Mark。

Function Objects Adapter(函数对象适配器)

标签:函数对象   适配器   adapter   

原文地址:http://blog.csdn.net/kzq_qmi/article/details/46516833

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!