array
1. 容器模板
具有固定长度的容器,其内部维护了一个内建数组,与内建数组相比提供了复制操作
std::array<int,3> a{1,2,3};
std::array<int,3> b = a;
2. 提供的接口
构造:
类似数组,聚合初始化;
缺省初始化可能会导致元素大小不确定;
成员类型(比如value_type):
#include <iostream>
#include <array>
#include <type_traits>
int main()
{
std::cout << std::is_same_v<std::array<int,3>::value_type,int> << std::endl;
}
此例中输出为:1
元素访问( [] ,at ,front ,back,data ) :
#include <iostream>
#include <array>
int main()
{
std::array<int,3> array{1,2,3};
std::cout << array[0] << std::endl;
std::cout << array.at(1) << std::endl;
std::cout << array.front() << " " << array.back() << std::endl;
std::cout << array.data() << std::endl;
}
相比[ ],访问方法at可以避免程序运行,输出一个莫名其妙的值,也就是访问不相关内存
front( ) 和 back( )方法分别输出数组里的第一个值和最后一个值
data( ) 方法返回 int 指针,指向数组里首个元素的地址
* 容量相关(平凡实现 empty , size , max_size ):
#include <iostream>
#include <array>
int main()
{
std::array<int, 3> array{1, 2, 3};
std::cout << array.empty() << std::endl;
std::cout << array.size() << std::endl;
std::cout << array.max_size() << std::endl;
}
其实这里size( ) 和 maxsize( ) 返回的都是3,这么做的原因就是C++为了统一接口,方便模板调用
** 填充与交换(fill , swap ): _**
#include <iostream>
#include <array>
int main()
{
std::array<int, 3> array{1, 2, 3};
array.fill(100);
for(auto i : array)
{
std::cout << i << std::endl;
}
}
输出:
100
100
100
#include <iostream>
#include <array>
int main()
{
std::array<int, 3> array1{1,2,3};
std::array<int, 3> array2{4,5,6};
array1.swap(array2);
for(auto i : array1)
{
std::cout << i << std::endl;
}
}
输出:
4
5
6
在array中,复制和交换数组的成本是较高的
比较操作(<=>):
#include <iostream>
#include <array>
int main()
{
std::array<int, 3> alice{1, 2, 3};
std::array<int, 3> bob{7, 8, 9};
std::array<int, 3> eve{1, 2, 3};
std::cout << std::boolalpha;
// Compare non equal containers
std::cout << "alice == bob returns " << (alice == bob) << '\n';
std::cout << "alice != bob returns " << (alice != bob) << '\n';
std::cout << "alice < bob returns " << (alice < bob) << '\n';
std::cout << "alice <= bob returns " << (alice <= bob) << '\n';
std::cout << "alice > bob returns " << (alice > bob) << '\n';
std::cout << "alice >= bob returns " << (alice >= bob) << '\n';
std::cout << '\n';
// Compare equal containers
std::cout << "alice == eve returns " << (alice == eve) << '\n';
std::cout << "alice != eve returns " << (alice != eve) << '\n';
std::cout << "alice < eve returns " << (alice < eve) << '\n';
std::cout << "alice <= eve returns " << (alice <= eve) << '\n';
std::cout << "alice > eve returns " << (alice > eve) << '\n';
std::cout << "alice >= eve returns " << (alice >= eve) << '\n';
输出:
alice == bob returns false
alice != bob returns true
alice < bob returns true
alice <= bob returns true
alice > bob returns false
alice >= bob returns false
alice == eve returns true
alice != eve returns false
alice < eve returns false
alice <= eve returns true
alice > eve returns false
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 效率较高
写操作可能会导致迭代器失效
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)
可读写