设为首页 加入收藏

TOP

C++函数配接器(一)
2017-02-08 08:16:48 】 浏览:518
Tags:函数

一、概述


? 配接器(adaptor)在STL组件的灵活运用功能上,扮演着轴承、转换器的角色,将一种容器或迭代器装换或封装成另一种容器或迭代器。adaptor这个概念,实际上是一种设计模式,其定义如下:


? 将一个class的接口转换为另一个class的接口,使原本因接口不兼容而不能合作的classes,可以一起运作。


配接器按功能可以分为如下3类:


可以改变函数或仿函数接口的适配器,称为仿函数适配器;


? ? 针对容器的适配器,称为容器适配器;


? ? 针对迭代器的适配器,称为迭代器适配器。


本博客只介绍仿函数适配器,在实际编程中比较常见。


二、什么是可配接对象


? 什么是可配接对象?看到这句话可能还云里雾里的,真不太明白,下面通过一个很简单的给数组排序的例子来解释一下。


#include


#include


#include


#include ? ? //ostream_iterator


using namespace std;


struct myLess


{


? ? ? ? bool operator()(int lhs, int rhs) const


? ? ? ? {?


? ? ? ? ? ? ? ? return lhs < rhs;


? ? ? ? }?


};


int main()


{


? ? ? ? int IntArray[] = {7,4,2,9,1};


? ? ? ? sort(IntArray, IntArray + sizeof(IntArray) / sizeof(int), myLess());


? ? ? ? copy(IntArray, IntArray + sizeof(IntArray) / sizeof(int), ostream_iterator(cout, "\n"));


? ? ? ? return 0;


}


?


#程序执行结果


1


2


4


7


9


? 可以看到这个程序正确执行了,现在我想让程序内的数组进行降序。当然你可以重新定义一个仿函数,但是我想用一个更快捷的方法,那就是not2函数。


//修改排序那一行的函数


sort(IntArray, IntArray + sizeof(IntArray) / sizeof(int), not2(myLess()));


?


? 但是我发现这样是编译不过的,为什么呢?这就回到我们的主题了,因为myLess不是一个可配接对象。那么如何让它变成一个可配接对象呢,继续往下看。


三、unary_function和binary_function


? 为什么刚刚写的myLess对象是不可配接的呢?因为它缺少argument_type、first_argument_type、second_argument_type和result_type这些特殊类型的定义。而unary_function和binary_function则可以提供这些类型的定义。我们在定义仿函数的时候,只需继承自这2个函数,那么我们的仿函数就是可配接的对象了。由于unary_function和binary_function是STL提供的模版,所以必须要指定必要的参数类型。


?


#include


#include


#include


#include ? ? //ostream_iterator


#include ? //binary_function, not2


using namespace std;


//第一个参数,第二个参数,返回值


struct myLess : public binary_function


{


? ? ? ? bool operator()(int lhs, int rhs) const


? ? ? ? {?


? ? ? ? ? ? ? ? return lhs < rhs;


? ? ? ? }?


};


int main()


{


? ? ? ? int IntArray[] = {7,4,2,9,1};


? ? ? ? sort(IntArray, IntArray + sizeof(IntArray) / sizeof(int), not2(myLess()));


? ? ? ? copy(IntArray, IntArray + sizeof(IntArray) / sizeof(int), ostream_iterator(cout, "\n"));


? ? ? ? return 0;


}



?


#程序执行结果


[root@oracle Documents]# ./a.out


9


7


4


2


1


? 传递给unary_function和binary_function的模版参数正是函数子类的operator()的参数类型和返回值。如果operator()接受一个参数,则使用unary_function<参数, 返回值>;如果operator()接受两个参数,则使用binary_function<参数1, 参数2, 返回值>。


? 一般情况下,传递给unary_function和binary_function的非指针类型需要去掉const和引用(&)部分。如下:


struct myLess : public binary_function


{


? ? ? ? bool operator()(const myClass &lhs, const myClass &rhs) const


? ? ? ? {?


? ? ? ? ? ? ? ? return lhs < rhs;


? ? ? ? }?


};


? 但是以指针作为参数或返回值的函数子类,一般规则是,传给unary_function和binary_function的类型与operator()的参数和返回类型完全相同。如下:


struct myLess : public binary_function


{


? ? ? ? bool operator()(const myClass *lhs, const myClass *rhs) const


? ? ? ? {?


? ? ? ? ? ? ? ? return lhs < rhs;


? ? ? ? }?


};


四、标准的函数配接器


1. not1和not2


? 这2个配接器都是对可配接对象的否定。上面已经介绍过使用方法了。那么什么时候用not1,什么时候用not2呢?


? 如果可配接对象的operator()接受一个参数则使用not1;如果可配接对象的operator()接受两个参数则使用not2。


2. bind1st和bind2nd


? bind1st表示我们绑定第一个参数,bind2st表示我们绑定第二个参数。


?


#include


#include


#include


#include ? ? //ostream_iterator


#include ? //binary_function, bind1st


using namespace std;


struct myLess : public binary_function


{


? ? ? ? bool operator()(int lhs, int rhs) const


? ? ? ? {?


? ? ? ? ? ? ? ? return lhs < rhs;


? ? ? ? }?


};


int main()


{


? ? ? ? int IntArray[] = {7,4,2,9,1};


? ? ? ? vector IntVec(IntArray, IntArray + sizeof(IntArray) / sizeof(int));


? ? ? ? IntVec.erase(remove_if(IntVec.begin(), IntVec.end(), bind1st(myLess(), 5)), IntVec.end());


? ? ? ? copy(IntVec.begin(), IntVec.end(), ostream_iterator(cout, "\n"));


? ? ? ? return 0;


}


?


#程序执行结果


[root@oracle Documents]# ./a.out


4


2


1


? bind1st(myLess(), 5)相当于把5赋值给lhs,那么表达式就变成 5 < rhs,所以7和9就被删除了。


? 如果把bind1st(myLess(), 5

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Linux IO多路复用 epoll 心得 下一篇C++标准库中各种排序归纳

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目