定义于头文件
类模板:
template<
class T,
class Allocator = std::allocator<T>
> class vector;
模板形参:
T - 元素的类型;
Allocator - 用于获取/释放内存及构造/析构内存中元素的分配器。
vector 上的常见操作复杂度(效率)如下:
随机访问——常数 (1)
在末尾插入或移除元素——均摊常数 (1)
插入或移除元素——与到 vector 结尾的距离成线性 (n)
定义:
// 1、默认构造函数
vector();
// 2、构造拥有给定分配器 alloc 的空容器。
explicit vector( const Allocator& alloc );
// 3、构造拥有 count 个有值 value 的元素的容器。
vector( size_type count,
const T& value,
const Allocator& alloc = Allocator());
// 4、构造拥有个 count 默认插入的 T 实例的容器。不进行复制。
explicit vector( size_type count, const Allocator& alloc = Allocator() );
// 5、构造拥有范围 [first, last) 内容的容器。
template< class InputIt >
vector( InputIt first, InputIt last,
const Allocator& alloc = Allocator() );
// 6、复制构造函数
vector( const vector& other );
// 7、构造拥有 other 内容的容器,以 alloc 为分配器。
vector( const vector& other, const Allocator& alloc );
// 8、移动构造函数
vector( vector&& other );
// 9、有分配器扩展的移动构造函数。
vector( vector&& other, const Allocator& alloc );
// 10、构造拥有 initializer_list init 内容的容器。
vector( std::initializer_list<T> init,
const Allocator& alloc = Allocator() );
用法:
// 1、默认构造函数
std::vector<std::string> words1;
// 3、构造拥有 count 个有值 value 的元素的容器
std::vector<std::string> words3(5, "Mo"); //words2 为 {"Mo", "Mo", "Mo", "Mo", "Mo"}
// 5、构造拥有范围 [first, last) 内容的容器
std::vector<std::string> words5(words3.begin(), words3.end());
// 6、复制构造函数
std::vector<std::string> words6(words5);
// 8、移动构造函数
std::vector<std::string> words8(std::move(words6));
// 10、C++ 11 初始化器列表语法:
std::vector<std::string> words10 {"the", "frogurt", "is", "also", "cursed"};
替换容器的内容。
定义:
vector& operator=( const vector& other ); // 复制赋值运算符。
vector& operator=( vector&& other ); // 移动赋值运算符。
vector& operator=( std::initializer_list<T> ilist ); // 以 initializer_list ilist 所标识者替换内容。
用法:
std::vector<int> nums1 {3, 1, 4, 6, 5, 9};
std::vector<int> nums2;
std::vector<int> nums3;
// 从 nums1 复制赋值数据到 nums2
nums2 = nums1;
// 从 nums1 移动赋值数据到 nums3,
nums3 = std::move(nums1);
// initializer_list 的复制赋值复制数据给 nums3
nums3 = {1, 2, 3};
替换容器的内容。
定义:
void assign( size_type count, const T& value ); // 以 count 份 value 的副本替换内容。
template< class InputIt > // 以范围 [first, last) 中元素的副本替换内容。
void assign( InputIt first, InputIt last );
void assign( std::initializer_list<T> ilist ); // 以来自 initializer_list ilist 的元素替换内容。
用法:
// 以 count 份 value 的副本替换内容
std::vector<char> characters;
characters.assign(5, 'a');
// 以范围 [first, last) 中元素的副本替换内容
std::vector<char> vchar;
vchar.assign(characters.begin(), characters.end());
// 以来自 initializer_list ilist 的元素替换内容
characters.assign({'\n', 'C', '+', '+', '1', '1', '\n'});
返回位于指定位置 pos 的元素的引用,有边界检查。
若 pos 不在容器范围内,则抛出 std::out_of_range 类型的异常。
定义:
reference at( size_type pos );
const_reference at( size_type pos ) const;
用法:
std::vector<int> vi = {1, 2, 3, 4, 5, 6};
vi.at(1) = 0; // 修改元素
std::cout << vi.at(2) << std::endl; // 获取元素
返回位于指定位置 pos 的元素的引用。不进行边界检查。
不同于 std::map::operator[] ,此运算符决不插入新元素到容器。通过此运算符访问不存在的元素是未定义行为。
定义:
reference operator[]( size_type pos );
const_reference operator[]( size_type pos ) const;
用法:
std::vector<int> vi = {1, 2, 3, 4, 5, 6};
vi[1] = 0; // 修改元素
std::cout << vi[2] << std::endl; // 获取元素
返回到容器首元素的引用。
对于容器 c ,表达式 c.front() 等价于 *c.begin() 。
定义:
reference front();
const_reference front() const;
用法:
std::vector<char> letters {'o', 'm', 'g', 'w', 't', 'f'};
if (!letters.empty()) {
std::cout << letters.front() << std::out; // 输出 o
}
返回到容器中最后一个元素的引用。
对于非空容器 c ,表达式 c.back() 等价于 *std::prev(c.end()) 。
定义:
reference back();
const_reference back() const;
用法:
std::vector<char> letters {'o', 'm', 'g', 'w', 't', 'f'};
if (!letters.empty()) {
std::cout << letters.back() << std::endl; // 输出 f
}
返回指向内存中数组第一个元素的指针。
定义:
T* data() noexcept;
const T* data() const noexcept;
用法:
std::vector<int> vi = {1, 2, 3, 4, 5, 6};
std::cout << vi.data() << std::endl; // 输出地址(例:0xbb1530)
std::cout << *(vi.data()) << std::endl; // 输出 1
返回指向 vector 首元素的迭代器。 cbegin中的c表示const,即返回const_iterator,不允许通过迭代器修改元素。
若 vector 为空,则返回的迭代器将等于 end() 。
定义:
iterator begin();
const_iterator cbegin() const noexcept;
用法:
std::vector<int> vi = {1, 2, 3, 4, 5, 6};
std::cout << *(vi.begin()) << std::endl; // 输出 1
*(vi.begin()) = 0;
std::cout << *(vi.cbegin()) << std::endl; // 输出 0
指向后随最后元素的迭代器。
定义:
iterator end();
const_iterator cend() const noexcept;
用法:
std::vector<char> vc;
if (vc.begin() == vc.end())
std::cout << "vector is empty." << std::endl;
返回指向逆向 vector 首元素的逆向迭代器。 它对应非逆向 vector 的末元素。若 vector 为空,则返回的迭代器等于 rend() 。
定义:
reverse_iterator rbegin();
const_reverse_iterator crbegin() const noexcept;
用法:
std::vector<int> vi = {1, 2, 3, 4, 5, 6};
std::cout << *(vi.rbegin()) << std::endl; // 输出 6
std::cout << *(vi.crbegin()) << std::endl; // 输出 6
返回指向逆向 vector 末元素后一元素的逆向迭代器。 它对应非逆向 vector 首元素的前一元素。此元素表现为占位符,试图访问它导致未定义行为。
定义:
reverse_iterator rend();
const_reverse_iterator crend() const noexcept;
用法:
std::vector<int> vi = {1, 2, 3, 4, 5, 6};
std::cout << *std::prev(vi.rend()) << std::endl; // 输出 1
std::cout << *std::prev(vi.crend()) << std::endl; // 输出 1
检查容器是否无元素,即是否 begin() == end() 。
定义:
bool empty() const;
用法:
vector<int> v;
bool flag = v.empty(); // 输出 true
返回容纳的元素数。
定义:
size_type size() const;
用法:
std::vector<int> nums {1, 3, 5, 7};
std::cout << nums.size() << std::endl; // 输出 4
返回根据系统或库实现限制的容器可保有的元素最大数量,即对于最大容器的 std::distance(begin(), end()) 。
定义:
size_type max_size() const;
用法:
std::vector<int> vi;
std::cout << vi.max_size() << std::endl; // 可能输出 4611686018427387903
std::vector<char> vc;
std::cout << vc.max_size() << std::endl; // 可能输出 18446744073709551615
增加 vector 的容量到大于或等于 new_cap 的值。 若 new_cap 大于当前的 capacity() ,则分配新存储,否则该方法不做任何事。
reserve() 不更改 vector 的 size 。
若 new_cap 大于 capacity() ,则所有迭代器,包含尾后迭代器和所有到元素的引用都被非法化。否则,没有迭代器或引用被非法化。
定义:
void reserve( size_type new_cap );
用法:
std::vector<int> v;
v.reserve(100);
返回容器当前已为之分配空间的元素数。
定义:
size_type capacity() const;
用法:
std::vector<int> v;
int cap = v.capacity();
请求移除未使用的容量。
它是减少 capacity() 到 size()非强制性请求。请求是否达成依赖于实现。
若发生重分配,则所有迭代器,包含尾后迭代器,和所有到元素的引用都被非法化。若不发生重分配,则没有迭代器或引用被非法化。
定义:
void shrink_to_fit();
用法:
std::vector<int> v;
std::cout << "Default-constructed capacity is " << v.capacity() << '\n';
v.resize(100);
std::cout << "Capacity of a 100-element vector is " << v.capacity() << '\n';
v.resize(50);
std::cout << "Capacity after resize(50) is " << v.capacity() << '\n';
v.shrink_to_fit();
std::cout << "Capacity after shrink_to_fit() is " << v.capacity() << '\n';
v.clear();
std::cout << "Capacity after clear() is " << v.capacity() << '\n';
v.shrink_to_fit();
std::cout << "Capacity after shrink_to_fit() is " << v.capacity() << '\n';
for (int i = 1000; i < 1300; ++i)
v.push_back(i);
std::cout << "Capacity after adding 300 elements is " << v.capacity() << '\n';
v.shrink_to_fit();
std::cout << "Capacity after shrink_to_fit() is " << v.capacity() << '\n';
//输出如下:
// Default-constructed capacity is 0
// Capacity of a 100-element vector is 100
// Capacity after resize(50) is 100
// Capacity after shrink_to_fit() is 50
// Capacity after clear() is 50
// Capacity after shrink_to_fit() is 0
// Capacity after adding 300 elements is 512
// Capacity after shrink_to_fit() is 300
从容器擦除所有元素。此调用后 size() 返回零。
非法化任何指代所含元素的引用、指针或迭代器。任何尾后迭代器亦被非法化。
保持 vector 的 capacity() 不变(注意:更改容量上的标准限制在 vector::reserve 的规定中)。
定义:
void clear();
用法:
std::vector<int> container{1, 2, 3};
container.clear();
std::cout << container.size() << std::endl; // 输出 0
std::cout << container.capacity() << std::endl; // 输出 3
插入元素到容器中的指定位置。
定义:
// 1、在 pos 前插入 value
iterator insert( iterator pos, const T& value );
// 2、在 pos 前插入 value
iterator insert( const_iterator pos, T&& value );
// 3、在 pos 前插入 value 的 count 个副本
void insert( iterator pos, size_type count, const T& value );
// 4、在 pos 前插入来自范围 [first, last) 的元素
template< class InputIt >
void insert( iterator pos, InputIt first, InputIt last);
// 5、在 pos 前插入来自 initializer_list ilist 的元素
iterator insert( const_iterator pos, std::initializer_list<T> ilist );
用法:
std::vector<int> vec(3,100);
// 1,2、在 pos 前插入 value
auto it = vec.begin();
it = vec.insert(it, 200); // 200 100 100 100
// 3、插入多个value
vec.insert(it,2,300); // 300 300 200 100 100 100
// "it" 不再合法,获取新值:
it = vec.begin();
// 4、在 pos 前插入来自范围 [first, last) 的元素
std::vector<int> vec2(2,400);
vec.insert(it+2, vec2.begin(), vec2.end()); // 300 300 400 400 200 100 100 100
// 5、在 pos 前插入来自 initializer_list ilist 的元素
int arr[] = { 501,502,503 };
vec.insert(vec.begin(), arr, arr+3); // 501 502 503 300 300 400 400 200 100 100 100
直接于 pos 前插入元素到容器中。
定义:
template< class... Args >
iterator emplace( const_iterator pos, Args&&... args );
用法:
std::vector<int> v {1, 2, 3};
v.emplace(v.begin() + 1, 4); // v : 1, 4, 2, 3
从容器擦除指定的元素。
定义:
// 1、移除位于 pos 的元素。
iterator erase( iterator pos );
// 2、移除范围 [first; last) 中的元素。
iterator erase( iterator first, iterator last );
用法:
std::vector<int> 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 (前开后闭,6没有被删除)
后附给定元素 value 到容器尾
定义:
// 1、初始化新元素为 value 的副本。
void push_back( const T& value );
// 2、移动 value 进新元素。
void push_back( T&& value );
用法:
std::vector<std::string> letters;
letters.push_back("abc"); // letters : "abc"
std::string s = "def";
letters.push_back(std::move(s)); // letters : "abc" "def" , s为空
重设容器大小以容纳 count 个元素。 若当前大小大于 count ,则减小容器为其首 count 个元素。若当前大小小于 count ,1) 则后附额外的默认插入的元素,2) 则后附额外的 value 的副本。
定义:
void resize( size_type count );
void resize( size_type count, const value_type& value );
用法:
std::vector<int> c = {1, 2, 3};
c.resize(5); // c : 1, 2, 3, 0, 0
c.resize(2); // c : 1, 2
将内容与 other 的交换。 不在单独的元素上调用任何移动、复制或交换操作。
定义:
void swap( vector& other );
用法:
std::vector<int> a1{1, 2, 3}, a2{4, 5};
a1.swap(a2);
利用 swap 缩小 vector 内存:
#include
#include
using namespace std;
int main() {
vector<int> v;
for (int i = 0; i < 100; ++i)
v.push_back(i);
cout << v.capacity() << endl; // 141
vector<int>(v).swap(v); //匿名对象
cout << v.capacity() << endl; // 100
return 0;
}
该过程的原理如下所示:
vector<int> v1;
for (int i = 0; i < 100; ++i)
v.push_back(i);
vector<int> v2(v1);
cout << v1.capacity() << endl; // 141
cout << v2.capacity() << endl; // 100,利用v1初始化v2,capacity = v1.size()
v1.swap(v2); // 交换两个容器
cout << v1.capacity() << endl; // 100
cout << v2.capacity() << endl; // 141
采用匿名函数的原理与上述原理相同,关键点是初始化使得 capacity = size,只不过使用匿名函数,在交换完成后,匿名函数就自动销毁了,因为本身就是用来缩小空间了,v2 后面用不到,故匿名函数省去了自己销毁。
检查 lhs 与 rhs 的内容是否相等,即它们是否拥有相同数量的元素且 lhs 中每个元素与 rhs 的同位置元素比较相等。
定义:
template< class T, class Alloc >
bool operator==( const std::vector<T,Alloc>& lhs,
const std::vector<T,Alloc>& rhs );
用法:
std::vector<int> alice{1, 2, 3};
std::vector<int> bob{7, 8, 9, 10};
std::vector<int> eve{1, 2, 3};
// 比较不相等的容器
std::cout << "alice == bob returns " << (alice == bob) << std::endl; //输出 false
// 比较相等的容器
std::cout << "alice == eve returns " << (alice == eve) << std::endl; //输出 true
为 std::vector 特化 std::swap 算法。交换 lhs 与 rhs 的内容。调用 lhs.swap(rhs) 。
定义:
template< class T, class Alloc >
void swap( std::vector<T,Alloc>& lhs,
std::vector<T,Alloc>& rhs );
用法:
std::vector<int> alice{1, 2, 3};
std::vector<int> bob{7, 8, 9, 10};
//交换容器
std::swap(alice,bob);
//交换后:alice : 7 8 9 10 bob : 1 2 3
从容器中擦除所有比较等于 value 的元素。(C++ 20)
定义:
template< class T, class Alloc, class U >
constexpr typename std::vector<T,Alloc>::size_type
erase(std::vector<T,Alloc>& c, const U& value);
用法:
std::vector<char> cnt {'1', '2', '3', '5', '6'};
auto erased = std::erase(cnt, '3');
从容器中擦除所有满足 pred 的元素。(C++ 20)
定义:
template< class T, class Alloc, class U >
constexpr typename std::vector<T,Alloc>::size_type
erase_if(std::vector<T,Alloc>& c, Pred pred);
用法:
std::vector<char> cnt {'1', '2', '3', '5', '6'};
std::erase_if(cnt,
[](char x) { return (x - '0') % 2 == 0; }
);