vector的使用,首先添加头文件 #include
vector 是封装动态数组的顺序容器。元素相继存储,不仅可通过迭代器,还能用指向元素的常规指针访问元素。vector 的存储是自动管理的,按需扩张收缩; vector 通常占用多于静态数组的空间,因为要分配更多内存以管理将来的增长; vector 所用的方式不在每次插入元素时,而只在额外内存耗尽时重分配。
1. 赋值函数 1.1 操作(operator) “=”函数接口(c++20):
constexpr vector& operator=( const vector& other );
函数作用:将 other 中的 vector 赋值给 “=” 之前的 vector;不是地址引用,是赋值重建;
常规使用示例:
vector1.2 assign(将值赋给容器)& nums1 = {3, 1, 4, 6, 5, 9}; vector & nums2; nums2 = nums1; //nums2 = {3, 1, 4, 6, 5, 9}; // 移动赋值 vector & nums3; nums3 = move(nums1); //nums3 = {3, 1, 4, 6, 5, 9}; nums1={}
函数接口(c++20):
1.2.1 以 count 份 value 的副本替换内容。constexpr void assign( size_type count, const T& value );
参数含义:
- count - 容器的新大小;
- value - 用以初始化容器元素的值 ;
常规使用示例:
vector1.2.2 以范围 [first, last) 中元素的副本替换内容。characters; characters.assign(5, 'a'); //characters={'a','a','a','a','a'}
constexpr void assign( InputIt first, InputIt last );
参数含义: first, last - 复制来源元素的范围
说明:若 InputIt 为整数类型,则此重载与1.2.1拥有相同效果。
常规使用示例:
vector1.3 vector的初始化 1.3.1 默认初始化characters; characters.assign({'C', '+', '+', '1', '1'}); // characters = “C++11”
vector1.3.2 赋值构造test1; //构造一个空的vector容器 vector test(7); //test={0,0,0,0,0,0},构造大小为7,其中值为0的vector容器 vector list(7,3); //list={3,3,3,3,3,3,3}
vector1.3.3 通过数组构造list = {1,2,3,4,5,6,7}; vector list{1,2,3,4,5,6,7}; vector list; list.assign(7,3); //list={3,3,3,3,3,3,3}
int a[] ={1,2,3,4,5};
vectorlist(a,a+5);
// (a,a+5)的含义为:a[0]-a[4];
//list3={1,2,3,4,5};
1.3.4 拷贝构造
vector2. 访问函数 2.1 访问指定元素list1 = {1,2,3,4,5,6,7}; vector list2(list1); //list2 = {1,2,3,4,5,6,7}; 等价于 vector list2 = list1; vector list3(list1.begin()+2, list1.end()-1); // list3={3,4,5,6}
vector2.1.1 at —— 访问指定的元素,同时进行越界检查data = { 1, 2, 4, 5, 7, 6 }; data[0]; // 1 data[4]; // 7
函数接口(c++20):
constexpr reference at( size_type pos );
参数含义:pos - 要返回的元素的位置 ;
函数作用:
- 返回位于指定位置 pos 的元素的引用,有边界检查;
- 若 pos 不在容器范围内,则抛出 out_of_range 类型的异常;
- 返回到所需元素的引用。
常规使用示例:
vector2.2.2 访问首尾元素data = { 1, 2, 4, 5, 5, 6 }; data.at(1) = 88; data.at(6) = 666; //索引 pos超限,报错 // data = { 1, 88, 4, 5, 5, 6 };
vector3. 迭代器 3.1 正向迭代器data = { 1, 2, 4, 5, 5, 6 }; 1.首元素 data.front(); // 1 2. 尾元素 data.back(); // 6
函数接口
1. 返回指向 vector 首元素的迭代器: constexpr iterator begin() noexcept; // 注意:若 vector 为空,则返回的迭代器将等于 end(); 2. 返回指向 vector 末元素后一元素的迭代器: constexpr iterator end() noexcept;
使用案例:
vector3.2 逆向迭代器nums; sort(nums.begin(), nums.end());
函数接口
1.返回指向第一个元素之前一个位置的反向迭代器。 constexpr const_reverse_iterator rend() const noexcept; 2.返回指向最后一个元素的反向迭代器; constexpr const_reverse_iterator rbegin() const noexcept;
使用案例:
vector4. 容量大小操作 4.1 检测是否为空values{1,2,3,4,5}; auto first = values.rbegin(); auto end = values.rend(); while (first != end) { cout << *first << " "; ++first; } // 5 4 3 2 1
若容器为空则返回 true ,否则返回 false vector4.2 元素数量values1{1,2,3,4,5}; vector values2; bool label1 = values1.empty(); // false bool label2 = values1.empty(); // true
vector4.3 改变容器中可存储元素的个数values1{1,2,3,4,5}; int n = values1.size(); // 5
函数接口(c++20):
1.重设容器大小以容纳 count 个元素,后附额外的默认插入的元素 constexpr void resize( size_type count ); 2.重设容器大小以容纳 count 个元素,后附额外的 value 的副本元素 constexpr void resize( size_type count, const value_type& value );
注意:若当前大小大于 count ,则减小容器为前 count 个元素。
常规使用示例:
vector4.4 存储空间 4.4.1 预留存储空间c = {1, 2, 3}; c.resize(5); // 1,2,3,0,0 c.resize(7,6); // 1,2,3,0,0,6,6 c.resize(2); // 1,2
函数接口(c++20):
constexpr void reserve( size_type new_cap ); // new_cap - vector 的新容量
作用:
- 增加 vector 的容量达到 new_cap;
- 若 new_cap 大于当前的 capacity() ,则分配新存储,否则该方法不做任何事;
- reserve() 不更改 vector 的 size;
- 若 new_cap 大于 capacity() ,则所有迭代器,包含尾后迭代器和所有到元素的引用都被非法化。否则,没有迭代器或引用被非法化。
使用案例:
vector4.4.2 返回当前存储空间能够容纳的元素数values(7); // values的容量为 7 values.reverse(100); // values的容量为 100
函数接口(c++20):
constexpr size_type capacity() const noexcept;
使用案例:
vector4.4.3 释放未使用的内存values1; vector values2(7); values1. int num = values1.capacity(); // 0 int num = values2.capacity(); // 7
函数接口(c++20):
constexpr void shrink_to_fit();
作用:
- 请求移除未使用的容量;
- 它是减少 capacity() 到 size()非强制性请求,请求是否达成依赖于实现;
- 若发生重分配,则所有迭代器,包含尾后迭代器,和所有到元素的引用都被非法化。若不发生重分配,则没有迭代器或引用被非法化。
使用案例:
vector5. 内容修改 5.1 清除元素 5.1.1 清除全部元素list; list.capacity(); // 0 list.resize(100); list.capacity(); // 100 list.resize(50); list.capacity(); // 100 list.shrink_to_fit(); list.capacity(); // 50
函数接口(c++20):
constexpr void clear() noexcept;
作用:
- 从容器擦除所有元素,此调用后 size() 返回零;
- 非法化任何指代所含元素的引用、指针或迭代器。任何尾后迭代器亦被非法化;
- 保持 vector 的 capacity() 不变。
使用案例:
vector5.1.2 擦除元素values{1,2,3,4,5}; values.size(); // 5 values.clear(); //values={} values.size(); // 0 values.capacity(); // 5
函数接口(c++20):
1.移除位于 pos 的元素 constexpr iterator erase( const_iterator pos ); 2.移除范围 [first; last) 中的元素 constexpr iterator erase( const_iterator first, const_iterator last );
注意:
- 能以 end() 迭代器为 pos 的值;
- 擦除空范围是无操作
返回值:最后移除元素的迭代器。
- 若 pos 指代末元素,则返回 end() 迭代器;
- 若在移除前 last == end() ,则返回更新的 end() 迭代器;
- 若 [first, last) 为空范围,则返回 last
使用案例:
vector5.1.3 移除末尾元素c{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; c.erase(c.begin()); // 1, 2, 3, 4, 5, 6, 7, 8, 9 c.erase(c.begin()+2, c.begin()+5); // 1, 2, 6, 7, 8, 9
函数接口(c++20):
constexpr void pop_back(); //移除容器的末元素。
使用案例:
vector5.2 构造元素 5.2.1 插入元素c{6, 7, 8, 9}; c.pop_back(); // 6,7,8
函数接口(c++20):
1.在 pos 前插入 value
constexpr iterator insert( const_iterator pos, const T& value );
2.在 pos 前插入 count 个 value
constexpr iterator insert( const_iterator pos, size_type count, const T& value );
3.在 pos 前插入 InputIt的[first,last)元素
constexpr iterator insert( const_iterator pos, InputIt first, InputIt last );
4.在 pos 前插入 ilist 的元素
constexpr iterator insert( const_iterator pos, std::initializer_list ilist );
参数含义:
- pos - 将内容插入到其前的迭代器。 pos 可为 end() 迭代器;
- value - 要插入的元素值;
- count - 要插入的元素数量;
- first, last - 要插入的元素范围,不能是指向调用 insert 所用的容器中的迭代器 ;
- ilist - 要插入的值来源的list ;
指向被插入 value 的迭代器。
常规使用示例:
vector5.2.2 原位构造元素vec(3,100); // 100,100,100 vec.insert(vec.begin(), 200); // 200,100,100,100 vec.insert(vec.begin(),2,300); // 300,300,200,100,100,100 vector vec2(2,400); auto it = vec.begin(); vec.insert(it+1, vec2.begin(), vec2.end()); // 300,400,400,300,200,100,100,100 int arr[] = { 501,502,503 }; vec.insert(vec.begin(), arr, arr+3); // 501,502,503,300,400,400,300,200,100,100,100
函数接口(c++20):
直接在 pos 前插入元素,返回指向被安置的元素的迭代器。 constexpr iterator emplace( const_iterator pos, Args&&... args ); // 其中,pos为构造新元素到其前的迭代器
注意:若新的 size() 大于 capacity() ,则所有迭代器和引用都被非法化。否则,仅在插入点前的迭代器和引用保持合法。尾后迭代器亦被非法化。
使用案例 :
vector5.2.3 将元素添加到容器末尾myvector = {10,20,30}; auto it = myvector.emplace ( myvector.begin()+1, 100 ); // 10,100,20,30 myvector.emplace ( it, 200 ); // 10,200,100,20,30 myvector.emplace ( myvector.end(), 300 ); // 10,200,100,20,30,300
函数接口(c++20):
constexpr void push_back( const T& value );
使用案例:
vector5.2.4 在容器末尾就地构造元素myvector = {10,20,30}; myvector.push_back(50); // 10,20,30,50
函数接口(c++20):
constexpr reference emplace_back( Args&&... args );
使用案例:
vector5.3 区别 5.3.1 insert 和 emplace 的区别myvector = {10,20,30}; myvector.emplace_back(50); // 10,20,30,50
insert是插入一个完全的对象,而emplace是先调用该对象的构造函数生成的对象,再把这个对象插入vector中。
使用emplace时,该对象类必须有相应的构造函数;
emplace 最大的作用是避免产生不必要的临时变量。
5.3.2 push_back 和 emplace_back 的区别push_back()方法要调用构造函数和复制构造函数,这也就代表着要先构造一个临时对象,然后把临时的copy构造函数拷贝或者移动到容器最后面;
emplace_back()则是直接在容器的尾部创建这个元素,省去了拷贝或移动元素的过程。
6. 两个vector 之间的内容交换函数接口(c++20)
将内容与 other 的交换,不在单个元素上调用任何移动、复制或交换操作。 constexpr void swap( vector& other ) noexcept();
使用案例:
vectora1{1, 2, 3}; vector a2{4, 5}; a1.swap(a2); // a1 = {4, 5}; // a2 = {1, 2, 3};



