array

1. 容器模板

具有固定长度的容器,其内部维护了一个内建数组,与内建数组相比提供了复制操作

  1. std::array<int,3> a{1,2,3};
  2. std::array<int,3> b = a;

2. 提供的接口

构造:
类似数组,聚合初始化;
缺省初始化可能会导致元素大小不确定;
成员类型(比如value_type):

  1. #include <iostream>
  2. #include <array>
  3. #include <type_traits>
  4. int main()
  5. {
  6. std::cout << std::is_same_v<std::array<int,3>::value_type,int> << std::endl;
  7. }

此例中输出为:1
元素访问( [] ,at ,front ,back,data ) :

  1. #include <iostream>
  2. #include <array>
  3. int main()
  4. {
  5. std::array<int,3> array{1,2,3};
  6. std::cout << array[0] << std::endl;
  7. std::cout << array.at(1) << std::endl;
  8. std::cout << array.front() << " " << array.back() << std::endl;
  9. std::cout << array.data() << std::endl;
  10. }

相比[ ],访问方法at可以避免程序运行,输出一个莫名其妙的值,也就是访问不相关内存
front( ) 和 back( )方法分别输出数组里的第一个值和最后一个值
data( ) 方法返回 int 指针,指向数组里首个元素的地址
* 容量相关(平凡实现 empty , size , max_size ):

  1. #include <iostream>
  2. #include <array>
  3. int main()
  4. {
  5. std::array<int, 3> array{1, 2, 3};
  6. std::cout << array.empty() << std::endl;
  7. std::cout << array.size() << std::endl;
  8. std::cout << array.max_size() << std::endl;
  9. }

其实这里size( ) 和 maxsize( ) 返回的都是3,这么做的原因就是C++为了统一接口,方便模板调用
**
填充与交换(fill , swap ): _**

  1. #include <iostream>
  2. #include <array>
  3. int main()
  4. {
  5. std::array<int, 3> array{1, 2, 3};
  6. array.fill(100);
  7. for(auto i : array)
  8. {
  9. std::cout << i << std::endl;
  10. }
  11. }

输出:

  1. 100
  2. 100
  3. 100
  1. #include <iostream>
  2. #include <array>
  3. int main()
  4. {
  5. std::array<int, 3> array1{1,2,3};
  6. std::array<int, 3> array2{4,5,6};
  7. array1.swap(array2);
  8. for(auto i : array1)
  9. {
  10. std::cout << i << std::endl;
  11. }
  12. }

输出:

  1. 4
  2. 5
  3. 6

在array中,复制和交换数组的成本是较高的
比较操作(<=>):

  1. #include <iostream>
  2. #include <array>
  3. int main()
  4. {
  5. std::array<int, 3> alice{1, 2, 3};
  6. std::array<int, 3> bob{7, 8, 9};
  7. std::array<int, 3> eve{1, 2, 3};
  8. std::cout << std::boolalpha;
  9. // Compare non equal containers
  10. std::cout << "alice == bob returns " << (alice == bob) << '\n';
  11. std::cout << "alice != bob returns " << (alice != bob) << '\n';
  12. std::cout << "alice < bob returns " << (alice < bob) << '\n';
  13. std::cout << "alice <= bob returns " << (alice <= bob) << '\n';
  14. std::cout << "alice > bob returns " << (alice > bob) << '\n';
  15. std::cout << "alice >= bob returns " << (alice >= bob) << '\n';
  16. std::cout << '\n';
  17. // Compare equal containers
  18. std::cout << "alice == eve returns " << (alice == eve) << '\n';
  19. std::cout << "alice != eve returns " << (alice != eve) << '\n';
  20. std::cout << "alice < eve returns " << (alice < eve) << '\n';
  21. std::cout << "alice <= eve returns " << (alice <= eve) << '\n';
  22. std::cout << "alice > eve returns " << (alice > eve) << '\n';
  23. std::cout << "alice >= eve returns " << (alice >= eve) << '\n';

输出:

  1. alice == bob returns false
  2. alice != bob returns true
  3. alice < bob returns true
  4. alice <= bob returns true
  5. alice > bob returns false
  6. alice >= bob returns false
  7. alice == eve returns true
  8. alice != eve returns false
  9. alice < eve returns false
  10. alice <= eve returns true
  11. alice > eve returns false
  12. alice >= eve returns true

vector

1.容器模板

2.提供的接口

与 array 很类似,但有其特殊性
容量相关接口:

附加元素接口: push_back / emplace_back

元素插入接口: insert / emplace

元素删除接口: pop_back / erase / clear
emplace/emplace_back相比其他两个效率可能会较高

3.注意

vector 不提供 push_front / pop_front ,可以使用 insert / erase 模拟,但效率不高
swap 效率较高
写操作可能会导致迭代器失效
image.png

list / deque / basic_string容器模板

list容器模板:双向链表

与vector相比,插入、删除操作成本较低,随机访问成本较高
提供了pop_front/splice等接口
写操作通常不会改变迭代器的有效性

forward_list 容器模板:单向链表

目标:一个成本较低的线性表实现
其迭代器只支持递增操作,因此无 rbegin/rend
不支持 size
不支持 pop_back / push_back
XXX_after 操作

适配器与生成器

类型适配器

basic_string_view(C++17)
不可进行写操作

span(C++20)
可读写

接口适配器

数值适配器

生成器