欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

容器库——std::vector

时间:2023-07-27
STL 文章目录

STL

1.std::vector

1.1成员类型1.2成员函数

1.2.1元素访问1.2.2迭代器1.2.3容量1.2.4修改器 1.std::vector 定义说明template< class T, class Allocator = std::allocator > class vector;std::vector 是封装动态数组的顺序容器。namespace pmr { template using vector = std::vector; }std::pmr::vector 是使用多态分配器的模板别名。(C++17 起)

vector 的存储是自动管理的,按需扩张收缩。 vector 通常占用多于静态数组的空间,因为要分配更多内存以管理将来的增长。 vector 所用的方式不在每次插入元素时,而只在额外内存耗尽时重分配。分配的内存总量可用capacity() 函数查询。额外内存可通过对 shrink_to_fit()的调用返回给系统。 (C++11 起)

重分配通常是性能上有开销的操作。若元素数量已知,则reserve()函数可用于消除重分配。

1.1成员类型

了解即可

1.2成员函数

构造函数、析构函数、operator=、assign、get_allocator

operator= :重构的赋值运算符,赋值给容器

get_allocator :返回相关的分配器

assign :将值赋给容器

函数说明void assign( size_type count, const T& value );以 count 份 value 的副本替换内容。template< class InputIt > void assign( InputIt first, InputIt last );以范围 [first, last) 中元素的副本替换内容void assign( std::initializer_list ilist );以来自 initializer_list ilist 的元素替换内容(C++11 起) 参数说明count容器的新大小value用以初始化容器元素的值first, last复制来源元素的范围ilist复制值来源的 initializer_list

示例

#include #include using namespace std;void assign_demo(){ vector characters; vector characters2; characters.assign(5, 'a'); characters2.assign(characters.begin(),characters.begin()+2); for (char c : characters) { cout << c << 'n'; } for (char c : characters2) { cout << c << endl; } initializer_list ilist = {'c','d'}; characters.assign(ilist); for (char c : characters) { cout << c << 'n'; }}int main(){ vector_demo(); return 0;}输出: a a a a a a a c d

1.2.1元素访问

at、operator[]、front、back、data

at :访问指定的元素,同时进行越界检查 函数说明reference at( size_type pos );返回位于指定位置 pos 的元素的引用,有边界检查,(接下行)const_reference at( size_type pos ) const;若 pos 不在容器范围内,则抛出 std::out_of_range 类型的异常。返回元素的引用 参数说明pos要返回的元素的位置

operator[] :访问指定的元素

front :访问第一个元素

函数说明reference front();返回到容器首元素的引用,(接下行)const_reference front() const;在空容器上对front的调用是未定义的

对于容器 c ,表达式c.front() 等价于 *c.begin()

back :访问最后一个元素 函数说明reference back();返回到容器中最后一个元素的引用。const_reference back() const;在空容器上对 back 的调用是未定义的。

对于容器 c ,表达式 return c.back();等价于{ auto tmp = c.end(); --tmp; return *tmp; }

data :返回指向内存中数组第一个元素的指针 函数说明T* data() noexcept;返回指向作为元素存储工作的底层数组的指针。对于非空容器,返回的指针与首元素地址比较相等。(C++11 起)const T* data() const noexcept;指针满足范围 [data(); data() + size()) 始终是合法范围,即使容器为空(该情况下 data() 不可解引用)。(C++11 起)

若 size()为 0 ,则 data()可能或可能不返回空指针。

示例

#include #include using namespace std;void visit_demo() { vector numbers{ 2, 4, 6, 8 }; cout << "Second element: " << numbers.at(1) << 'n'; cout << "Second element: " << numbers[1] <<'n'; cout << "First element: " << numbers.front() << endl; cout << "First element: " << *numbers.data() << endl; cout << "Last element: " << numbers.back() << endl; numbers.at(1) = 3; numbers[2] = 5; numbers.front() = 0; *numbers.data() = 1; numbers.back() = 7; cout << "All numbers:"; for (auto i : numbers) { cout << ' ' << i; } cout << 'n';}int main() { //vector_demo(); visit_demo(); return 0;}输出: Second element: 4Second element: 4First element: 2First element: 2Last element: 8All numbers: 1 3 5 7

1.2.2迭代器

begin、cbegin;end、cend;rbegin、crbegin;rend,crend;

begin、cbegin :返回指向容器第一个元素的迭代器 函数说明iterator begin();返回指向容器首元素的迭代器。(C++11 前)iterator begin() noexcept;若容器为空,则返回的迭代器将等于end()。(C++11 起)const_iterator begin() const;(C++11 前)const_iterator begin() const noexcept;(C++11 起)const_iterator cbegin() const noexcept;(C++11 起)

end、cend :返回指向容器尾端的迭代器 函数说明iterator end();返回指向容器末元素后一元素的迭代器。(C++11 前)iterator end() noexcept;此元素表现为占位符;试图访问它导致未定义行为。(C++11 起)const_iterator end() const;(C++11 前)const_iterator end() const noexcept;(C++11 起)const_iterator cend() const noexcept;(C++11 起)

rbegin、crbegin :返回指向容器最后元素的逆向迭代器 函数说明reverse_iterator rbegin();返回指向逆向容器首元素的逆向迭代器。(C++11 前)reverse_iterator rbegin() noexcept;它对应非逆向容器的末元素。(C++11 起)const_reverse_iterator rbegin() const;(C++11 前)const_reverse_iterator rbegin() const noexcept;(C++11 起)const_reverse_iterator crbegin() const noexcept;(C++11 起)

rend、crend :返回指向前端的逆向迭代器 函数说明reverse_iterator rend();返回指向逆向容器末元素后一元素的逆向迭代器。(C++11 前)reverse_iterator rend() noexcept;它对应非逆向容器首元素的前一元素。(C++11 起)const_reverse_iterator rend() const;此元素表现为占位符,试图访问它导致未定义行为。(C++11 前)const_reverse_iterator rend() const noexcept;(C++11 起)const_reverse_iterator crend() const noexcept;(C++11 起)

示例

#include using namespace std;#include #include #include void iterator_demo() { vector ints{ 1, 2, 4, 8, 16 }; vector fruits{ "orange", "apple", "raspberry" }; vector empty; cout << "ints: "; for (vector::const_iterator it = ints.cbegin(); it != ints.cend(); it++) cout<< *it << " "; cout << endl; cout << "reverse of ints:"; for (auto it = ints.rbegin(); it != ints.rend(); ++it) cout << *it << " "; cout << endl; // 打印 vector fruits 中的首个水果,而不检查是否有一个。 cout << "First fruit: " << *fruits.begin() << "n"; if (empty.begin() == empty.end()) cout << "vector 'empty' is indeed empty.n";}int main() { //vector_demo(); //visit_demo(); iterator_demo(); return 0;}输出: ints: 1 2 4 8 16reverse of ints:16 8 4 2 1First fruit: orangevector 'empty' is indeed empty.

1.2.3容量

empty、size、max_size、reserve、capacity、shrink_to_fit

empty :检查容器是否为空 函数说明bool empty() const;检查容器是否无元素,即是否 begin() == end() 。(C++11 前)bool empty() const noexcept;(C++11 起) (C++20 前)[[nodiscard]] bool empty() const noexcept;(C++20 起)

size :返回容纳的元素数 函数说明size_type size() const;返回容器中的元素数,即 std::distance(begin(), end()) 。(C++11 前)size_type size() const noexcept;(C++11 起)

max_size :返回可容纳的最大元素数 函数说明size_type max_size() const;返回根据系统或库实现限制的容器可保有的元素最大数量(C++11 前)size_type max_size() const noexcept;,即对于最大容器的 std::distance(begin(), end()) 。(C++11 起)

此值通常反映容器大小上的理论极限,至多为std::numeric_limits::max()。运行时,可用 RAM 总量可能会限制容器大小到小于 max_size() 的值。

reserve :预留存储空间 函数说明void reserve( size_type new_cap );增加 vector 的容量到大于或等于 new_cap 的值。若 new_cap 大于当前的capacity() ,则分配新存储,否则该方法不做任何事。

reserve() 不更改 vector 的 size 。

若 new_cap 大于 capacity(),则所有迭代器,包含尾后迭代器和所有元素的引用都被非法化。否则,没有迭代器或引用被非法化。

不能用 reserve() 减少容器容量。为该目的提供的是shrink_to_fit()。

正确使用 reserve() 能避免不必要的分配,但不适当地使用 reserve() (例如在每次 push_back()调用前调用它)可能会实际增加重分配的数量(通过导致容量线性而非指数增长)并导致计算复杂度增加,性能下降。

capacity :返回当前存储空间能够容纳的元素数 函数说明size_type capacity() const;返回容器当前已为之分配空间的元素数。(C++11 前)size_type capacity() const noexcept;(C++11 起)

shrink_to_fit :通过释放未使用的内存减少内存的使用 函数说明void shrink_to_fit();请求移除未使用的容量。(C++11 起)

它是减少capacity()到 size()非强制性请求。请求是否达成依赖于实现。

若发生重分配,则所有迭代器,包含尾后迭代器,和所有到元素的引用都被非法化。若不发生重分配,则没有迭代器或引用被非法化。

示例

#include using namespace std;#include #include #include void capacity_demo() { cout << boolalpha;//启用流 str 中的 boolalpha 标志 vector numbers; cout << "Initially, numbers.empty(): " << numbers.empty() << 'n'; numbers.push_back(42); cout << "After adding elements, numbers.empty(): " << numbers.empty() << 'n'; vector nums{ 1, 3, 5, 7 }; cout << "nums contains " << nums.size() << " elements.n"; vector s; cout << "Maximum size of a 'vector' is " << s.max_size() << "n"; int sz = 100; cout << "not using reserve: n"; vector v1; v1.push_back(10); v1.push_back(10); cout << sizeof(v1) << " bytes" << endl; cout << "Capacity is " << v1.capacity() << endl; std::cout << "using reserve: n"; v1.reserve(sz); cout << sizeof(v1) << " bytes" << endl; cout << "Capacity is " <

1.2.4修改器

clear、insert、emplace、erase、push_back、emplace_back、pop_back、resize、swap

clear 清除内容 函数void clear();(C++11 前)void clear() noexcept;(C++11 起)

从容器擦除所有元素。此调用后 size()返回零。

非法化任何指代所含元素的引用、指针或迭代器。任何尾后迭代器亦被非法化。

保持 vector 的capacity()不变

insert 插入元素 函数说明iterator insert( iterator pos, const T& value );在 pos 前插入 value 。(C++11 前)iterator insert( const_iterator pos, const T& value );(C++11 起)iterator insert( const_iterator pos, T&& value );(C++11 起)void insert( iterator pos, size_type count, const T& value );在 pos 前插入 value 的 count 个副本(C++11 前)iterator insert( const_iterator pos, size_type count, const T& value );(C++11 起)template< class InputIt > void insert( iterator pos, InputIt first, InputIt last);在 pos 前插入来自范围 [first, last) 的元素(C++11 前)template< class InputIt > iterator insert( const_iterator pos, InputIt first, InputIt last );(C++11 起)iterator insert( const_iterator pos, std::initializer_list ilist );在 pos 前插入来自 initializer_list ilist 的元素。(C++11 起)

插入元素到容器中的指定位置。

若新size()大于旧capacity()则导致重分配。 若新的size()大于capacity(),则所有迭代器和引用都被非法化。否则,仅在插入点前的迭代器和引用保持合法。尾后迭代器亦被非法化。

emplace 原位构造元素 函数template< class… Args > iterator emplace( const_iterator pos, Args&&… args );直接于 pos 前插入元素到容器中。(C++11 起)

直接于 pos 前插入元素到容器中。通过std::allocator_traits::construct构造元素,它典型地用布置 new 在容器所提供的位置原位构造元素。将参数 args..、作为 std::forward)(args)… 转发给构造函数。

若新的 size()大于capacity() ,则所有迭代器和引用都被非法化。否则,仅在插入点前的迭代器和引用保持合法。尾后迭代器亦被非法化。

erase 擦除元素 函数说明iterator erase( iterator pos );移除位于 pos 的元素。(C++11 前)iterator erase( const_iterator pos );(C++11 起)iterator erase( iterator first, iterator last );移除范围 [first; last) 中的元素。(C++11 前)iterator erase( const_iterator first, const_iterator last );(C++11 起)

从容器擦除指定的元素。

非法化位于擦除点或之后的迭代器,包含end()迭代器。

迭代器 pos 必须合法且可解引用。从而不能以 end()迭代器(合法,但不可解引用)为 pos 的值。

若 first==last 则迭代器 first 不必可解引用:擦除空范围是无操作。

push_back 将元素添加到容器尾 函数说明void push_back( const T& value );初始化新元素为 value 的副本。void push_back( T&& value );移动 value 进新元素。(C++11 起)

后附给定元素 value 到容器尾。

若新的size()大于capacity(),则所有迭代器和引用(包含尾后迭代器)都被非法化。否则仅尾后迭代器被非法化。

emplace_back 在容器末尾就地构造元素 函数template< class… Args > void emplace_back( Args&&… args );(C++11 起) (C++17 前)template< class… Args > reference emplace_back( Args&&… args );(C++17 起)

添加新元素到容器尾。元素通过std::allocator_traits::construct 构造,它典型地用布置 new 于容器所提供的位置原位构造元素。参数 args..、以std::forward(args)… 转发到构造函数。

若新的size()大于capacity(),则所有迭代器和引用(包含尾后迭代器)都被非法化。否则仅尾后迭代器被非法化。

emplace_back 可避免用 push_back 时的额外复制或移动操作

pop_back 移除末元素 函数void pop_back();移除容器的最末元素。

在空容器上调用 pop_back 是未定义的。

非法化指向末元素的迭代器和引用,以及end()迭代器。

resize 改变容器中可存储元素的个数 函数void resize( size_type count );(1)(C++11 起)void resize( size_type count, const value_type& value );(2)(C++11 起)

重设容器大小以容纳 count 个元素。

若当前大小 大于 count ,则减小容器为其首 count 个元素。

若当前大小 小于 count ,则后附额外元素,并以 value 的副本初始化。(C++11 前)

若当前大小 小于 count ,

​ 1) 则后附额外的默认插入的元素

​ 2) 则后附额外的 value 的副本(C++11 起)

swap 交换内容 函数说明void swap( vector& other );将内容与 other 的交换。(C++17 前)void swap( vector& other ) noexcept();不在单个元素上调用任何移动、复制或交换操作。(C++17 起)

所有迭代器和引用保持合法。尾后迭代器被非法化。

若 std::allocator_traits::propagate_on_container_swap::value 为 true ,则用非成员 swap 的非限定调用交换分配器。否则,不交换它们(且若 get_allocator() != other.get_allocator() ,则行为未定义)。(C++11 起)

示例

#include using namespace std;#include #include #include void revise_demo() { vector vec{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; print_vec(vec); vec.erase(vec.begin());//1 print_vec(vec); vec.erase(vec.begin() + 2, vec.begin() + 5);//2 print_vec(vec); vec.pop_back(); cout << "After using pop_back:" ; print_vec(vec); vec.clear(); cout << "After using clear:"; print_vec(vec); vec = vector(3, 100); auto it = vec.begin(); it = vec.insert(it, 200);//在it位置插入200,返回begin() vec.insert(it, 2, 300);//在it位置插入两个300 print_vec(vec); // "it" 不再合法,获取新值: it = vec.begin(); vector vec2(2, 400); vec.insert(it + 2, vec2.begin(), vec2.end());//在it+2的位置插入vec2 print_vec(vec); int arr[] = { 501,502,503 }; vec.insert(vec.begin(), arr, arr + 3);//在begin()处插入arr print_vec(vec); struct President { string name; string country; int year; President(string p_name, string p_country, int p_year) : name(move(p_name)), country(move(p_country)), year(p_year) { cout << "I am being constructed.n";//构造函数 } President(President&& other) : name(move(other.name)), country(move(other.country)), year(other.year) { cout << "I am being moved.n";//拷贝构造函数 } President& operator=(const President& other) = default; }; vector elections; cout << "emplace_back:n"; elections.emplace_back("Nelson Mandela", "South Africa", 1994);//不会调用拷贝构造函数 vector reElections; cout << "npush_back:n"; reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));//会调用拷贝构造函数 vector c = { 1, 2, 3 }; vector c2 = { 4,5,6 }; cout << "nThe vector holds: "; print_vec(c); c.resize(5); cout << "After resize up to 5: "; print_vec(c); c.resize(2); cout << "After resize down to 2: "; print_vec(c); c.swap(c2); cout << "After swap with c2: "; print_vec(c);}int main() { //vector_demo(); //visit_demo(); //iterator_demo(); //capacity_demo(); revise_demo(); return 0;}输出: 0 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 6 7 8 9After using pop_back: 1 2 6 7 8After using clear: 300 300 200 100 100 100 300 300 400 400 200 100 100 100 501 502 503 300 300 400 400 200 100 100 100emplace_back:I am being constructed.push_back:I am being constructed.I am being moved.The vector holds: 1 2 3After resize up to 5: 1 2 3 0 0After resize down to 2: 1 2After swap with c2: 4 5 6

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。