Skip to content

std::vector

ucas-zc-learning edited this page Oct 28, 2022 · 13 revisions

向量(Vector)是一个封装了动态大小数组的顺序容器(Sequence Container)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,向量是一个能够存放任意类型的动态数组。
容器特性:1)顺序序列,顺序容器中的元素按照严格的线性顺序排序。可以通过元素在序列中的位置访问对应的元素;2)动态数组,支持对序列中的任意元素进行快速直接访问,甚至可以通过指针算述进行该操作,提供了在序列末尾相对快速地添加/删除元素的操作;3)能够感知内存分配器,容器使用一个内存分配器对象来动态地处理它的存储需求。
1.构造函数
参考C++ API文档,std::vector构造函数共有10个,如下所示:
1)默认构造函数。构造拥有默认构造的分配器的空容器,复杂度为常数。

vector(); (C++17 前)
vector() noexcept(noexcept(Allocator())); (C++17 起)(C++20 前)
constexpr vector() noexcept(noexcept(Allocator())); (C++20 起)

2)构造拥有给定分配器alloc的空容器,复杂度为常数。

explicit vector( const Allocator& alloc ); (C++17 前)
explicit vector( const Allocator& alloc ) noexcept; (C++17 起)(C++20 前)
constexpr explicit vector( const Allocator& alloc ) noexcept; (C++20 起)

3)构造拥有count个有值value的元素的容器,复杂度与count成线性。

explicit vector(size_type count, const T& value = T(), const Allocator& alloc = Allocator()); (C++11 前)
vector(size_type count, const T& value, const Allocator& alloc = Allocator()); (C++11 起)(C++20 前)
constexpr vector(size_type count, const T& value, const Allocator& alloc = Allocator()); (C++20 起)

4)构造拥有个count默认插入的T实例的容器。不进行复制,复杂度与count成线性。

explicit vector(size_type count); (C++11 起)(C++14 前)
explicit vector(size_type count, const Allocator& alloc = Allocator()); (C++14 起)(C++20 前)
constexpr explicit vector(size_type count, const Allocator& alloc = Allocator()); (C++20 起)

5)构造拥有范围[first, last)内容的容器,复杂度与first和last的距离成线性。

template<class InputIt>vector(InputIt first, InputIt last, const Allocator& alloc = Allocator()); (C++20 前)
template<class InputIt>constexpr vector(InputIt first, InputIt last, const Allocator& alloc = Allocator()); (C++20 起)

6)复制构造函数。构造拥有other内容的容器,如同通过调用std::allocator_traits<allocator_type>::select_on_container_copy_construction(other.get_allocator())获得分配器,复杂度与other的大小成线性。

vector(const vector& other); (C++20 前)
constexpr vector(const vector& other); (C++20 起)

7)构造拥有other内容的容器,以alloc为分配器,复杂度与other的大小成线性。

vector( const vector& other, const Allocator& alloc ); (C++11 起)(C++20 前)
constexpr vector( const vector& other, const Allocator& alloc ); (C++20 起)

8)移动构造函数。用移动语义构造拥有other内容的容器。分配器通过属于other的分配器移动构造获得。移动后,保证other为empty(),复杂度为常数。

vector( vector&& other ); (C++11 起)(C++17 前)
vector( vector&& other ) noexcept; (C++17 起)(C++20 前)
constexpr vector( vector&& other ) noexcept; (C++20 起)

9)有分配器扩展的移动构造函数。以alloc为新容器的分配器,从other移动内容;若alloc != other.get_allocator(),则它导致逐元素移动。(该情况下,移动后不保证other为空),若alloc != other.get_allocator()则复杂度为线性,否则为常数。

vector( vector&& other, const Allocator& alloc ); (C++11 起)(C++20 前)
constexpr vector( vector&& other, const Allocator& alloc ); (C++20 起)

10)构造拥有initializer_list init内容的容器,复杂度与init的大小成线性。

vector( std::initializer_list init, const Allocator& alloc = Allocator() ); (C++11 起)(C++20 前)
constexpr vector( std::initializer_list init, const Allocator& alloc = Allocator() ); (C++20 起)

2.析构函数

~vector(); (C++20 前)
constexpr ~vector(); (C++20 起)

销毁vector。调用元素的析构函数,然后解分配所用的存储。注意,若元素是指针,则不销毁所指向的对象,复杂度与vector大小成线性。

3.std::vector<T,Allocator>::operator=
->复制赋值运算符
other 的副本替换内容。若 std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::valuetrue ,则以源分配器的副本替换目标分配器。若源分配器与目标分配器不比较相等,则用目标 *this 分配器销毁内存,然后在复制元素前用 other 的分配器分配。(C++11起)。

vector& operator=( const vector& other ); (C++20 前)
constexpr vector& operator=( const vector& other ); (C++20 起)

复杂度*thisother 的大小成线性。

->移动赋值运算符
用移动语义以 other 的内容替换内容(即从 other 移动 other 中的数据到此容器)。之后 other 在合法但未指定的状态。若 std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::valuetrue ,则用源分配器的副本替换目标分配器。若它为 false 且源与目标分配器不比较相等,则目标不能取走源内存的所有权,而必须单独移动赋值逐个元素,用自己的分配器按需分配额外的内存。任何情况下,原先在 *this 中的元素要么被销毁,要么以逐元素移动赋值替换。

vector& operator=( vector&& other ); (C++11 起)(C++17 前)
vector& operator=( vector&& other ) noexcept(/* see below */); (C++17 起)(C++20 前)
constexpr vector& operator=( vector&& other ) noexcept(/* see below */); (C++20 起)

复杂度*this 的大小成线性,除非分配器不比较相等且不传播,该情况下与 *thisother 的大小成线性。

->initializer_list ilist 所标识者替换内容

vector& operator=( std::initializer_list ilist ); (C++11 起)(C++20 前)
constexpr vector& operator=( std::initializer_list ilist ); (C++20 起)

复杂度*thisilist 的大小成线性。

4.std::vector<T,Allocator>::assign(替换容器的内容)
->countvalue 的副本替换内容

void assign( size_type count, const T& value ); (C++20 前)
constexpr void assign( size_type count, const T& value ); (C++20 起)

复杂度count 成线性。

->以范围 [first, last) 中元素的副本替换内容
若任一参数是指向 *this 中的迭代器则行为未定义。

template< class InputIt >void assign( InputIt first, InputIt last ); (C++20 前)
template< class InputIt >constexpr void assign( InputIt first, InputIt last ); (C++20 起)

复杂度firstlast 间的距离成线性。

->以来自 initializer_list ilist 的元素替换内容

void assign( std::initializer_list ilist ); (C++11 起)(C++20 前)
constexpr void assign( std::initializer_list ilist ); (C++20 起)

复杂度以来自 initializer_list ilist 的元素替换内容。

5.std::vector<T,Allocator>::get_allocator
返回与容器关联的分配器

allocator_type get_allocator() const; (C++11 前)
allocator_type get_allocator() const noexcept; (C++11 起)(C++20 前)
constexpr allocator_type get_allocator() const noexcept; (C++20 起)

复杂度为常数级。

6、元素访问
->std::vector<T,Allocator>::at
返回位于指定位置 pos 的元素的引用,有边界检查
pos 不在容器范围内,则抛出 std::out_of_range 类型的异常。

reference at( size_type pos ); (C++20 前)
constexpr reference at( size_type pos ); (C++20 起)
const_reference at( size_type pos ) const; (C++20 前)
constexpr const_reference at( size_type pos ) const; (C++20 起)

复杂度为常数级别。
->std::vector<T,Allocator>::operator[]
返回位于指定位置 pos 的元素的引用。不进行边界检查

reference operator[]( size_type pos ); (C++20 前)
constexpr reference operator[]( size_type pos ); (C++20 起)
const_reference operator[]( size_type pos ) const; (C++20 前)
constexpr const_reference operator[]( size_type pos ) const; (C++20 起)

不同于 std::map::operator[] ,此运算符决不插入新元素到容器。通过此运算符访问不存在的元素是未定义行为。
复杂度为常数。
->std::vector<T,Allocator>::front
返回到容器首元素的引用。
在空容器上对 front 的调用是未定义的。

reference front(); (C++20 前)
constexpr reference front(); (C++20 起)
const_reference front() const; (C++20 前)
constexpr const_reference front() const; (C++20 起)

复杂度为常数。 ->std::vector<T,Allocator>::back
返回到容器最后一个元素的引用。
在空容器上对 back 的调用是未定义的。

reference back(); (C++20 前)
constexpr reference back(); (C++20 起)
const_reference back() const; (C++20 前)
constexpr const_reference back() const; (C++20 起)

复杂度为常数。
->std::vector<T,Allocator>::data
返回指向作为元素存储工作的底层数组的指针。
指针满足范围 [data(); data() + size()) 始终是合法范围,即使容器为空(该情况下 data() 不可解引用)。

T* data() noexcept; (C++11 起)(C++20 前)
constexpr T* data() noexcept; (C++20 起)
const T* data() const noexcept; (C++11 起)(C++20 前)
constexpr const T* data() const noexcept; (C++20 起)

复杂度为常数。

7.迭代器
->std::vector<T,Allocator>::begin, std::vector<T,Allocator>::cbegin
返回指向 vector 首元素的迭代器。
vector 为空,则返回的迭代器将等于 end()

iterator begin(); (C++11 前)
iterator begin() noexcept; (C++11 起)(C++20 前)
constexpr iterator begin() noexcept; (C++20 起)
const_iterator begin() const; (C++11 前)
const_iterator begin() const noexcept; (C++11 起)(C++20 前)
constexpr const_iterator begin() const noexcept; (C++20 起)
const_iterator cbegin() const noexcept; (C++11 起)(C++20 前)
constexpr const_iterator cbegin() const noexcept; (C++20 起)

复杂度为常数。
->std::vector<T,Allocator>::end, std::vector<T,Allocator>::cend
返回指向 vector 末元素后一元素的迭代器。
此元素表现为占位符;试图访问它导致未定义行为

iterator end(); (C++11 前)
iterator end() noexcept; (C++11 起)(C++20 前)
constexpr iterator end() noexcept; (C++20 起)
const_iterator end() const; (C++11 前)
const_iterator end() const noexcept; (C++11 起)(C++20 前)
constexpr const_iterator end() const noexcept; (C++20 起)
const_iterator cend() const noexcept; (C++11 起)(C++20 前)
constexpr const_iterator cend() const noexcept; (C++20 起)

复杂度为常数。
->std::vector<T,Allocator>::rbegin, std::vector<T,Allocator>::crbegin
返回指向逆向 vector 首元素的逆向迭代器。
它对应非逆向 vector 的末元素。若 vector 为空,则返回的迭代器等于 rend()

reverse_iterator rbegin(); (C++11 前)
reverse_iterator rbegin() noexcept; (C++11 起)(C++20 前)
constexpr reverse_iterator rbegin() noexcept; (C++20 起)
const_reverse_iterator rbegin() const; (C++11 前)
const_reverse_iterator rbegin() const noexcept; (C++11 起)(C++20 前)
constexpr const_reverse_iterator rbegin() const noexcept; (C++20 起)
const_reverse_iterator crbegin() const noexcept; (C++11 起)(C++20 前)
constexpr const_reverse_iterator crbegin() const noexcept; (C++20 起)

复杂度为常数。
->std::vector<T,Allocator>::rend, std::vector<T,Allocator>::crend
返回指向逆向 vector 末元素后一元素的逆向迭代器。
它对应非逆向 vector 首元素的前一元素。此元素表现为占位符,试图访问它导致未定义行为

reverse_iterator rend(); (C++11 前)
reverse_iterator rend() noexcept; (C++11 起)(C++20 前)
constexpr reverse_iterator rend() noexcept; (C++20 起)
const_reverse_iterator rend() const; (C++11 前)
const_reverse_iterator rend() const noexcept; (C++11 起)(C++20 前)
constexpr const_reverse_iterator rend() const noexcept; (C++20 起)
const_reverse_iterator crend() const noexcept; (C++11 起)(C++20 前)
constexpr const_reverse_iterator crend() const noexcept; (C++20 起)

复杂度为常数。

Clone this wiki locally