定义于头文件 <vector>
template< class T, | (1) | |
namespace pmr { template <class T> | (2) | (C++17 起) |
1) std::vector
是封装动态数组的顺序容器。
2) std::pmr::vector
是使用多态分配器的模板别名。
元素相继存储,这意味着不仅可通过迭代器,还能用指向元素的常规指针访问元素。这意味着指向 vector 元素的指针能传递给任何期待指向数组元素的指针的函数。 | (C++03 起) |
vector 的存储是自动管理的,按需扩张收缩。 vector 通常占用多于静态数组的空间,因为要分配更多内存以管理将来的增长。 vector 所用的方式不在每次插入元素时,而只在额外内存耗尽时重分配。分配的内存总量可用 capacity() 函数查询。额外内存可通过对 shrink_to_fit() 的调用返回给系统。 (C++11 起)
重分配通常是性能上有开销的操作。若元素数量已知,则 reserve() 函数可用于消除重分配。
vector 上的常见操作复杂度(效率)如下:
- 随机访问——常数 O(1)
- 在末尾插入或移除元素——均摊常数 O(1)
- 插入或移除元素——与到 vector 结尾的距离成线性 O(n)
std::vector
(对于 bool
以外的 T
)满足容器 (Container) 、具分配器容器 (AllocatorAwareContainer) 、序列容器 (SequenceContainer) 、连续容器 (ContiguousContainer) (C++17 起)及可逆容器 (ReversibleContainer) 的要求。
修改器
清除内容
std::vector<T,Allocator>::clear
void clear(); | (C++11 前) | |
void clear() noexcept; | (C++11 起) |
从容器擦除所有元素。此调用后 size() 返回零。
非法化任何指代所含元素的引用、指针或迭代器。任何尾后迭代器亦被非法化。
保持 vector
的 capacity() 不变(注意:更改容量上的标准限制在 vector::reserve
的规定中,见 [1] )。
参数
(无)
返回值
(无)
复杂度
与容器大小,即元素数成线性。
擦除元素
std::vector<T,Allocator>::erase
iterator erase( iterator pos ); | (1) | (C++11 前) |
iterator erase( const_iterator pos ); | (C++11 起) | |
iterator erase( iterator first, iterator last ); | (2) | (C++11 前) |
iterator erase( const_iterator first, const_iterator last ); | (C++11 起) |
从容器擦除指定的元素。
1) 移除位于 pos
的元素。
2) 移除范围 [first; last)
中的元素。
非法化位于擦除点或之后的迭代器,包含 end() 迭代器。
迭代器 pos
必须合法且可解引用。从而不能以 end() 迭代器(合法,但不可解引用)为 pos
的值。
若 first==last
则迭代器 first
不必可解引用:擦除空范围是无操作。
参数
pos | - | 指向要移除的元素的迭代器 |
first, last | - | 要移除的元素范围 |
类型要求 | ||
- T 必须满足可移动赋值 (MoveAssignable) 的要求。 |
返回值
后随最后被移除元素的迭代器。若迭代器 pos
指代最后元素,则返回 end() 迭代器。
异常
不抛出,除非 T
的赋值运算符抛异常。
复杂度
线性:调用 T 析构函数的次数与被擦除的元素数相同,调用 T 赋值运算符的次数与 vector 中被擦除元素后的元素数相等。
移除末元素
std::vector<T,Allocator>::pop_back
void pop_back(); |
移除容器的最末元素。
在空容器上调用 pop_back
是未定义的。
非法化指向末元素的迭代器和引用,以及 end() 迭代器。
参数
(无)
返回值
(无)
复杂度
常数。
异常
(无)
交换内容
std::vector<T,Allocator>::swap
void swap( vector& other ); | (C++17 前) | |
void swap( vector& other ) noexcept(/* see below */); | (C++17 起) |
将内容与 other
的交换。不在单个元素上调用任何移动、复制或交换操作。
所有迭代器和引用保持合法。尾后迭代器被非法化。
若 std::allocator_traits<allocator_type>::propagate_on_container_swap::value 为 true ,则用非成员 | (C++11 起) |
参数
other | - | 要与之交换内容的容器 |
返回值
(无)
异常
(无) | (C++17 前) |
noexcept 规定: noexcept(std::allocator_traits<Allocator>::propagate_on_container_swap::value | (C++17 起) |
复杂度
常数。
调用示例
#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
#include <functional>
#include <time.h>
#include <vector>
using namespace std;
struct Cell
{
int x;
int y;
Cell() = default;
Cell(int a, int b): x(a), y(b) {}
Cell &operator +=(const Cell &cell)
{
x += cell.x;
y += cell.y;
return *this;
}
Cell &operator +(const Cell &cell)
{
x += cell.x;
y += cell.y;
return *this;
}
Cell &operator *(const Cell &cell)
{
x *= cell.x;
y *= cell.y;
return *this;
}
Cell &operator ++()
{
x += 1;
y += 1;
return *this;
}
bool operator <(const Cell &cell) const
{
if (x == cell.x)
{
return y < cell.y;
}
else
{
return x < cell.x;
}
}
bool operator >(const Cell &cell) const
{
if (x == cell.x)
{
return y > cell.y;
}
else
{
return x > cell.x;
}
}
bool operator ==(const Cell &cell) const
{
return x == cell.x && y == cell.y;
}
};
std::ostream &operator<<(std::ostream &os, const Cell &cell)
{
os << "{" << cell.x << "," << cell.y << "}";
return os;
}
int main()
{
std::cout << std::boolalpha;
std::mt19937 g{std::random_device{}()};
srand((unsigned)time(NULL));
auto generate = []()
{
int n = std::rand() % 10 + 110;
Cell cell{n, n};
return cell;
};
//3) 构造拥有 count 个有值 value 的元素的容器。
std::vector<Cell> vector1(3, generate());
//替换容器的内容。1) 以 count 份 value 的副本替换内容。
std::cout << "vector1: ";
std::copy(vector1.begin(), vector1.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
std::cout << std::endl;
//3) 构造拥有 count 个有值 value 的元素的容器。
std::vector<Cell> vector2(5, {101, 101});
//替换容器的内容。1) 以 count 份 value 的副本替换内容。
std::cout << "vector2: ";
std::copy(vector2.begin(), vector2.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
std::cout << std::endl;
//将内容与 other 的交换。不在单个元素上调用任何移动、复制或交换操作。
//所有迭代器和引用保持合法。尾后迭代器被非法化。
std::cout << "swap before:" << std::endl;
std::cout << "vector1: ";
std::copy(vector1.begin(), vector1.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
std::cout << "vector2: ";
std::copy(vector2.begin(), vector2.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
vector1.swap(vector2);
std::cout << "swap after:" << std::endl;
std::cout << "vector1: ";
std::copy(vector1.begin(), vector1.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
std::cout << "vector2: ";
std::copy(vector2.begin(), vector2.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
std::cout << std::endl;
//从容器擦除所有元素。此调用后 size() 返回零。
//非法化任何指代所含元素的引用、指针或迭代器。任何尾后迭代器亦被非法化。
//保持 vector 的 capacity() 不变
std::cout << "clear before:" << std::endl;
std::cout << "vector2.size(): " << vector2.size() << std::endl;
std::cout << "vector2.data(): " << vector2.data() << std::endl;
vector2.clear();
std::cout << "clear after:" << std::endl;
std::cout << "vector2.size(): " << vector2.size() << std::endl;
std::cout << "vector2.data(): " << vector2.data() << std::endl;
std::cout << std::endl;
std::vector<Cell> vector3(6, generate());
std::generate(vector3.begin(), vector3.end(), generate);
std::cout << "vector3: ";
std::copy(vector3.begin(), vector3.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
//从容器擦除指定的元素。1) 移除位于 pos 的元素。
vector3.erase(vector3.begin());
std::cout << "iterator erase( iterator pos ) after: " << std::endl;
std::cout << "vector3: ";
std::copy(vector3.begin(), vector3.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
//从容器擦除指定的元素。2) 移除范围 [first; last) 中的元素。
vector3.erase(vector3.begin() + 1, vector3.end() - 1);
std::cout << "iterator erase( iterator pos ) after: " << std::endl;
std::cout << "vector3: ";
std::copy(vector3.begin(), vector3.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
std::cout << std::endl;
//移除容器的最末元素。在空容器上调用 pop_back 是未定义的。
//非法化指向末元素的迭代器和引用,以及 end() 迭代器。
vector3.pop_back();
std::cout << "vector3: ";
std::copy(vector3.begin(), vector3.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
return 0;
}
输出