<vector>
Construct:
vector(); // vector<int> vec;
vector(size_type n); // vector<int> vec(10);
vector(size_type n,const value_type& val); // vector<int> backupVec(vec.size(), 250);
vector(const vector& x); // vector<int> backupVec(vec);
vector(InputIterator first, InputIterator last); // vector<int> backupVec(vec.begin(), vec.end());
int myints[] = {16,23,18,77};
vector<int> vec(myints, myints+sizeof(myints)/sizeof(ints)); // 数组仍然可以初始化 vector
vector<int> vec({1, 2, 3, 4});
vector<int> vec{1, 2, 3, 4};
vector<int> vec = {1, 2, 3, 4}; // 这个也可以
Operator:
vector<int> v1 = {1, 2, 3};
vector<int> v2 = {0};
v2 = v1; // copy ,此时 v2 也是 {1,2,3}
Iterators:
iterator begin(); // auto it = vec.begin(); it != vec.end(); it++ 顺序遍历
const_iterator begin();
iterator end(); // 返回 vector 最后元素的下一个位置 [begin, end)
const_iterator end();
reverse_iterator rbegin(); // auto it = vec.rbegin(); it != vec.rend(); it++ 逆序遍历
const_reverse_iterator rbegin();
reverse_iterator rend();
const_reverse_iterator rend();
const_iterator cbegin(); // C++ 11 only
const_iterator cend(); // C++ 11 only
const_reverse_iterator crbegin(); // C++ 11 only
const_reverse_iterator crend(); // C++ 11 only
iterator 与 const_iterator 比较 : (与其类似的还有 reference 与 const_reference)
1, 二者都是用来遍历和访问容器内的值。 iterator 可以改变所指向的元素值,而 const_iterator 不可以。
2, iterator 只可以遍历 非const vector,而不可以遍历 const vector。 (const vector<int> vec; // 该 vec 只可以用 const_iterator 来遍历)
3, const_iterator 对象可以用于 const vector 或 非const vector,它自身的值可以改变(可以指向其他元素),但不可以改写其指向的元素值。
4, 若只是遍历 vector (不涉及修改元素值), 可以使用 auto it = vec.begin() , 这样无论是 vector 还是 const vector 都可以遍历。
#include <iostream>
#include <vector>
using namespace std;
#define PRINT_VEC(vec, it) \
do { \
for (it = (vec).begin(); it != (vec).end(); it++) { \
cout << *it << " "; \
} \
cout << endl; \
} while(0)
#define RESET_VEC(vec, it, val) \
do { \
for (it = (vec).begin(); it != (vec).end(); it++) { \
*it = val; \
} \
} while(0)
int main() {
/*
验证 iterator 和 const_iterator 都可以遍历 非const vector
验证 iterator 可以修改所指向元素的值,而 const_iterator 不可以
*/
vector<int> vec{ 1, 2, 3, 4 }; // 非const vector
vector<int>::iterator it;
PRINT_VEC(vec, it); // 正确,iterator 遍历 非const vector
RESET_VEC(vec, it, 0); // 正确, iterator 可以修改所指向元素的值
vector<int>::const_iterator const_it;
PRINT_VEC(vec, const_it); // 正确,const_iterator 遍历 非const vector
//RESET_VEC(vec, const_it, 1); // 错误, 错在了 *const_it = 1; 不可以修改 const_iterator 所指向元素的值
/*
验证 iterator 不可以遍历 const vector,而 const_iterator 可以
*/
const vector<int> const_vec{ 1, 2, 3, 4 };
//PRINT_VEC(const_vec, it); // 错误,iterator 不可以遍历 const vector
PRINT_VEC(const_vec, const_it); // 正确, const_iterator 可以遍历 const vector
return 0;
}
const iterator 与 const_iterator 是不同的
前者是被 const 修饰的 iterator,声明一个 const iterator 时,必须初始化它(C++ 的 const 常量在声明时都必须初始化),且不能使它指向其他元素(const 常量不可更改),但可以修改它所指向元素的值(因为它是 iterator)。
后者是 const_iterator,它不可以改写指向的元素值,但是自身可以 ++ 或 -- 以遍历 vector。
Capacity:
size_type size(); // 当前容器中元素的个数
size_type max_size(); // 可能达到的最大容量,但不做保证
size_type capacity(); // 当前已申请的空间可容纳的元素个数
void resize(size_type n); // 改变当前 vector 的 size, 若 n < size,则去除多余的元素; 若 n > size, 则多余的元素以默认值填充
void resize(size_type n, const value_type& val); // 若 n > size,则多余的元素以指定值填充
bool empty(); // 判断当前 vector 是否为空
void reserve(size_type n); // 要求 vector 至少足以包括 n 个元素,若 n > capacity,则会导致 vector 重新申请空间,使得 capacity >= n。其他情况则无效。该函数不会导致 vector 中元素发生变化
void shrink_to_fit(); // C++ 11 only, 要求 vector 减少 capacity 已适应现有 size。该函数不会导致现有元素发生改变。
Element access:
reference operator[] // 通过 [index] 来访问 vector 元素,不会检查是否越界,若越界,则会出现 undefined behavior
const_reference operator[]
reference at(size_type n); // 与 [] 访问相似,多了个越界异常检测,当 n >= vec.size() 时,会抛出 out_of_range 的异常
const_reference at(size_type n);
reference front(); // 返回第一个 vector 的元素,若 vector 为空,则运行会出现 undefined behavior
const_reference front();
reference back(); // 返回最后一个 vector 的元素,若 vector 为空,则运行会出现 undefined behavior
const_reference back();
value_type* data(); // C++ 11 only
const value_type* data(); // C++ 11 only
data() 的作用:
返回指向向量内部使用的内存数组的直接指针,给用户在特殊情况下直接读取或操作底层数组
data() 有何意义:
比如有个库函数 : void test(const int* arr, int len);
你有个 vector<int> vec;
则可以这样操作: test(vec.data(), vec.size());
Modifiers:
void assign(InputIterator first, InputIterator last); // 将新内容分配给向量,替换当前内容,并相应地修改其大小。vec1.assign(vec2.begin(), vec2.end()); 将 vec2 的所有值赋值给 vec1
void assign(size_type n, const value_type& val); // 将 vector 重新初始化为 n 个 val 元素的容器 vec.assign(3, 0);
void assign(initializer_list<value_type> il); // 将 vector 重新初始化 vec.assign({-1, -2, -3});
void push_back(value_type& val);
void push_back(const value_type& val); // 在 vector 尾部插入一个元素
void emplace_back(Args&&... args); // 在 vector 尾部插入一个元素
void pop_back(); // 弹出 vector 尾部的一个元素
push_back 和 emplace_back 的区别:
两者的区别在于底层实现的机制不同。 push_back 向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自动销毁先前创建的这个元素).
而 emplace_back 在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。
emplace_back 是 C++ 11 出现的,若是为了兼容以前程序,则还是使用 push_back ,否则尽量使用 emplace_back。
iterator insert(const_iterator position, const value_type& val); // 向指定位置前插入元素,返回指向新插入元素的第一个迭代器
iterator insert(const_iterator position, size_type n, const value_type& val); // 向指定位置前插入 n 个元素
iterator insert(const_iterator position, InputIterator first, InputIterator last); // 在指定位置前插入 [begin,last) 元素
iterator insert(const_iterator position, initializer_list<value_type> il);
iterator emplace(const_iterator postion, Args&&... args); // 与 insert 功能相同, 底层实现机制不同
iterator erase(const_iterator position); // 移除指定位置的元素,返回指向移除元素后的迭代器
iterator erase(const_iterator first, const_iterator last); // 移除 [first,last) ,返回 last
void swap(vector& x); // 交换两个 vector 的内容
void clear(); // 清空容器 vector<T>().swap(x); // clear x reallocating
<vector> 中除了 vector 之外,还有一个特殊的 vector<bool>, 它和正常的 vector<T> 是有所区别的:
1, 它的出现是为了解决存储容量的问题
2, 它是以 bit 的方式来存储 bool ,而不是 Byte
3, vector<bool>::reference 返回的 reference 并非是 bool ,而是一个可以和 bool 兼容的代理数据类型
4, operator[] 操作返回的 reference 是一个右值,而不是左值