当前位置:   article > 正文

C++的STL适配器_c++ stl 适配器

c++ stl 适配器

一、背景介绍

适配器在STL组件中,扮演着转换器的角色。适配器是一种在已有容器的基础上,为其增加一些新的特性或功能的方法。而适配器这个概念,就是设计模式中的适配器模式。

注:适配器模式:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。

STL所提供的适配器,可以分为三类:

1、容器适配器,改变容器的接口
2、迭代器适配器,改变迭代器的接口
3、仿函数适配器,改变仿函数的接口

二、容器适配器

STL提供了序列式容器,同时提供了应用于不同场景的容器适配器。通俗的讲,适配器就是以序列式容器为底层数据结构,为适应场景而进一步封装了的的容器。需要注意的是,适配器不是STL中的容器类型,而是在已有容器上提供了新的接口或功能。

STL中提供了三种容器适配器,分别为stack,queue和priority_queue。默认的情况下,stack和queue基于deque而实的,priority_queue在vector上实现的。queue要求要有push_front操作因此不能建立在vector上面,priority_front要求有随机访问的功能,因此建立在vector上面。

种类默认顺序容器可用顺序容器说明
stackdequevector、list、deque
queuedequelist、deque基础容器必须提供push_front()运算
priority_queuevectorvector、deque基础容器必须提供随机访问功能

stack的底层由 deque构成从以下接口可清楚看出 stack与 deque的关系 

  1. template <class T, class Sequence = deque<T> >
  2. class stack
  3. {
  4. Sequence c;//底层容器
  5. ../
  6. };

 下面demo演示了stack适配器类的用法

  1. #include <iostream>
  2. #include <queue>
  3. using namespace std;
  4. #include <iostream>
  5. #include <stack>
  6. using namespace std;
  7. int main() {
  8. stack<int> s;
  9. for (int i = 1; i <= 5; i++) s.push(i);
  10. while (!s.empty()) {
  11. cout << s.top() << " ";
  12. s.pop();
  13. }
  14. system("pause");
  15. return 0;
  16. }

三、迭代器适配器

STL迭代器适配器是一种在已有迭代器的基础上,增加一些新的功能,以满足各种使用需求的方法。包括 insert_iterators、reverse_iterators、iostream_iterators。
3.1、insert_Iterators

用于将元素插入到容器的任意位置中。用法如下:

  1. #include <iostream>
  2. #include <vector>
  3. #include <list>
  4. #include <iterator>
  5. using namespace std;
  6. int main() {
  7. vector<int> a = {1, 2, 3};
  8. list<int> b;
  9. auto it = back_inserter(b);
  10. copy(a.begin(), a.end(), it);
  11. for (auto i : b) cout << i << " ";
  12. return 0;
  13. }


3.2、reverse_Iterators

reverse_iterator用于将迭代器进行反转,使原本应该前进的 operator++ 变成了后退操作,使原本应该后退的 operator-- 变成了前进操作。

  1. #include <iostream>
  2. #include <vector>
  3. #include <iterator>
  4. using namespace std;
  5. int main() {
  6. vector<int> a = {1, 2, 3};
  7. auto it = a.rbegin();
  8. while (it != a.rend()) {
  9. cout << *it << " ";
  10. it++;
  11. }
  12. return 0;
  13. }


3.3、IOstream_Iterators

用于将容器中的元素输出到输出流中。

  1. #include <iostream>
  2. #include <vector>
  3. #include <iterator>
  4. using namespace std;
  5. int main() {
  6. vector<int> a = {1, 2, 3};
  7. copy(a.begin(), a.end(), ostream_iterator<int>(cout, " "));
  8. return 0;
  9. }
  10. // 输出结果为:1 2 3。

四、仿函数适配器

在STL中,仿函数适配器是一种在已有函数对象的基础上,增加一些新的功能,以满足各种使用需求的方法。这些适配器包括绑定(bind)、函数(functiom)、否定(negate)、以及对一般函数或成员函数的修饰。

bind

用于将一个函数对象(函数)的部分参数绑定后返回一个新的函数对象。用法如下:

  1. #include <iostream>
  2. #include <functional>
  3. using namespace std;
  4. int foo(int a, int b) {
  5. return a * b;
  6. }
  7. int main() {
  8. auto f1 = bind(foo, 10, placeholders::_1);
  9. cout << f1(5) << endl;
  10. auto f2 = bind(foo, placeholders::_2, placeholders::_1);
  11. cout << f2(5, 10) << endl;
  12. return 0;
  13. }

输出结果分别为:5050

function

用于存储任意可调用对象,包括函数、函数指针、成员函数和仿函数等。用法如下:

  1. #include <iostream>
  2. #include <functional>
  3. using namespace std;
  4. int foo(int a, int b) {
  5. return a * b;
  6. }
  7. class Foo {
  8. public:
  9. int bar(int a, int b) {
  10. return a + b;
  11. }
  12. };
  13. int main() {
  14. function<int(int, int)> f1 = foo;
  15. cout << f1(2, 3) << endl;
  16. Foo f;
  17. function<int(Foo*, int, int)> f2 = &Foo::bar;
  18. cout << f2(&f, 2, 3) << endl;
  19. return 0;
  20. }

输出结果分别为:65

negate

对于一个一元函数对象,返回其相反数(即对于任意参数x,返回-f(x))。例如:

  1. #include <iostream>
  2. #include <functional>
  3. using namespace std;
  4. int main() {
  5. negate<int> f;
  6. cout << f(5) << endl;
  7. return 0;
  8. }

参考:

C++ STL(第四篇:适配器)_YoungYangD的博客-CSDN博客_stl适配器

STL学习系列之六—容器适配器_飞天絮雪的博客-CSDN博客d
C++ STL priority_queue容器适配器详

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/197925
推荐阅读
相关标签
  

闽ICP备14008679号