Function Objects 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。

时间: 2024-10-18 10:24:49

Function Objects Adapter(函数对象适配器)的相关文章

大数据技术之_23_Python核心基础学习_03_函数 + 对象(12.5小时)

第五章 函数5.1 函数的简介5.2 函数的参数5.3 函数参数传递的方式5.4 函数的不定长参数5.5 函数的返回值5.6 函数的文档字符串--函数的说明5.7 变量的作用域与命名空间5.8 函数的递归5.9 高阶函数5.10 函数的闭包5.11 装饰器--扩展函数的功能第六章 对象6.1 面向对象6.2 类的简介6.3 类的定义+类的属性和方法6.4 类的特殊方法6.5 封装6.5.1 隐藏类中的属性6.5.2 property 装饰器6.6 继承6.6.1 继承的简介6.6.2 方法的重写

设计模式之适配器模式 adapter 适配器模式分类概念角色详解 类适配器 对象适配器 接口适配器 双向适配器

现实世界中的适配器模型 先来看下来几个图片,截图自淘宝 上图为港版的插头与港版的插座 上图为插座适配器卖家的描述图 上图为适配后的结果 现实世界中适配器模式 角色分类 这就是适配器模式在电源插座上的应用 我们看下在插座适配器中的几个重要角色 可以看得出来,大陆和港版插座面板,都是作为电源的角色,他们的功能是相似的或者说相近的 插头要使用插座,进而接通电流 现实世界到代码的转换 电源插座代码示例 港版插座面板 package adapter; /**目标角色 Target 接口 * 香港地区使用的

js面向对象系列——Function函数对象

Function到底是什么东西? 1. Function是最顶层的构造器,它构造了系统中所有的对象,包括Object(Object是最顶层的对象,但要明确的知道Object也是一个函数,也是有Function构成的),Array,Date等 2. 一切都是对象,所以理论上理解Function也是一个对象,我们可以称为函数对象 这里简单介绍一下另一个重要的工具:instanceof 作用:检验对象的类型 function TestObject(){} TestObject instanceof O

认识js函数对象(Function Object)

认识函数对象(Function Object) 可以用function关键字定义一个函数,对于每个函数可以为其指定一个函数名,通过函 数名来进行调用.这些都是代码给用户的印象,而在JavaScript解释执行的时候,实际上每 个函数都是被维护为一个对象,这就是本小节将要介绍的函数对象(Function Object). 函数对象与其它用户所定义的对象有着本质的区别,这一类对象被称之为内部对象,例 如日期对象(Date).数组对象(Array).字符串对象(String)都是属于内部对象.换句话

关于Function()函数对象的那些小九九

概念:首先,函数是一种特殊类型的数据,函数也是数据类型的一种,实际上函数也是一种对象,函数对象的内建构造器是Function(); 函数的几种创建方式: 函数声明法: function sum(a,b){ return a+b;  } ; 函数文本标识法 var  sum = function(a,b){ return a+b; }: 函数构造器法 var sum= new Function('a','b','return a+b;') ; 使用函数构造器法创建的函数,其参数和代码段,都是以字符

适配器模式(Adapter):类适配器、对象适配器

适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口.A d a p t e r 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 适用场景: 1.已经存在的类的接口不符合我们的需求: 2.创建一个可以复用的类,使得该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作: 3.在不对每一个都进行子类化以匹配它们的接口的情况下,使用一些已经存在的子类. 通用类图: 我们生活中常常听到的是 电源适配器,它是用于电流变换(整流)的设备.适配器的

C++ 11 - STL - 函数对象(Function Object) (上)

1. 定义 在STL中,可以把函数传递给算法,也可以把函数对象传递给算法. 那么,什么是函数对象呢? 我们来看下它的声明: class X { public: // define function call operator return-value operator() (arguments) const; ... } 你可以这样调用:X fo; ... fo(arg1, arg2); 我们来看个简单的打印的例子 PrintInt.h #ifndef Print_Int_H_ #define

std::function&quot;函数&quot;对象包装器

语义: 类模板std::function是可调用对象的包装器,可以包装除了类成员之外的所有可调用对象.包括,普通函数,函数指针,lambda,仿函数.通过指定的模板参数,它可以用统一的方式保存,并延迟执行它们.所谓的延迟执行,就是回调了. 它使得C++对C的兼容性更强了. 常规多态案例: #include <iostream> #include <functional> using namespace std; class Operator { public: virtual in

C++STL 预定义函数对象和函数适配器

预定义函数对象和函数适配器 预定义函数对象基本概念:标准模板库STL提前定义了很多预定义函数对象,#include <functional> 必须包含. 1使用预定义函数对象: void main() { plus<int> intAdd; int x = 10; int y = 20; int z = intAdd(x, y); //等价于 x + y cout << z << endl; plus<string> stringAdd; str