C++11 adapter介绍
前言
适配器这个概念我其实直到现在都还没有理解,不过我在刷面经的时候偶尔能看到这个面试点,所以咱们就一起来看看。(C++就是这样啊,真的会问的非常深入的)
粗浅的理解容器适配器
这还是在看完了ccyanxyz的文章后才豁然开朗。首先呢,adapter不仅仅只有容器适配器,它有约三个大的方面,分别是容器适配器、仿函数适配器、迭代器适配器。咱们先把容器适配器的概念讲清楚了,帮助你理解什么是适配器。
咱们都有手机,手机都有充电器。充电器接受的是220V的电压,然后这个手机充电器干了啥呢?它就是将220V的交流电源,转换成了手机使用的低电压直流电。
我是学自动化的,对强电也稍微了解一点。我能不能自己发挥点本领直接使用这220V的交流电给手机充电?当然可以啊,肯定行啊,我自有我的方法。但是我能这么干么?估计我也不是很敢这么干,毕竟那是220V,稍微一不小心我就GG。
好了,例子讲完了,咱们现在回到容器适配器上。C++11里有三个容器适配器,他们是stack,queue和priority_queue。咱们对这仨肯定很熟悉,老朋友了。可是你知道,他们底层是如何实现的么?你听说过C++的deque么?你难道不觉得,这个deque既可以用来当做stack,又可以用来当做queue么???同样的,你肯定听过vector,那你难道不觉得,vector也可以拿来做priority_queue用么?
好了,这下你就应该清楚了,咱们的容器适配器,其实就是底层容器deque或者vector在功能上的特化与封装。我当然可以直接用deque来当做stack用,肯定可以啊。不过我一般不这么做,就像是我不会直接拿220V电来给手机充电一样,原理上都是行得通的,但是适配器就将这个功能直接帮你做好,而且还不会有误操作的风险。
种类 | 默认顺序容器 | 可用顺序容器 | 说明 |
---|---|---|---|
stack | deque | vector、list、deque | |
queue | deque | list、deque | 基础容器必须提供push_front()运算 |
priority_queue | vector | vector、deque | 基础容器必须提供随机访问功能 |
迭代器适配器
其实看完了上面的一部分,你应该就非常能理解适配器的含义了,所以这里的迭代器适配器肯定难不倒你。
C++ STL标准库给咱们提供了这些迭代器适配器:
1.插入迭代器适配器
这个很好理解,就是将你平常的一些给对象添加数据的操作转换成插入操作,然后搞成适配器给你用。这样的插入迭代器适配器有三种,分别是front_insert_iterator、back_insert_iterator和insert_iterator。看着很简单对吧?用起来也非常简单,这里就拿尾部插入迭代器适配器举个例子:
std::back_insert_iterator<Container> back_it (container);
2.反向迭代器适配器
这个就更好理解了。对这个迭代器适配器进行的自增操作其实是在实际地址上减少,这在一些反向算法中有便捷。
3.IO迭代器适配器
可以将迭代器绑定到某个 iostream 对象上。绑定到 istream 对象身上的,称为 istream_iterator,拥有输入功能;绑定到 ostream 对象身上的,称为 ostream_iterator,拥有输出功能。这种迭代器运用于屏幕输出非常方便。
仿函数适配器
这个仿函数我乍一听,还有点蒙,仔细了解了一下,我确实不会,之前压根就没写过,咱们先来一起了解一下什么是仿函数。
仿函数
首先说明一点:仿函数不是函数,而是类。只是用这个类的时候像个函数一样,本质上是类里重载了()运算符。
再说说为啥要搞这么个东西。
比如count_if函数,它接受的第三个参数只能是一个一元形参函数,但是咱们就想传递一个二元参数的函数进去咋办?这个时候仿函数就起作用了。