3.3 标准库类型 vector
3.3 标准库类型 vector
标准库类型vector
表示对象的集合,其中所有对象的类型都相同。集合中的每个对象有一个与之对应的索引,索引用于访问对象。也被称为容器(container)
要想使用vector
,必须包含适当的头文件。使用如下声明
#include <vector>
using std::vector;
模板本身不是类或函数,模板可以看做为编译器生成类或函数编写的一份说明。编译器根据模板创建类或函数的过程称为实例化,当使用模板时,需要指出编译器应把类或函数实例化成何种类型。对于类模板来说,我们通过提供一些额外信息来指定模板到底实例化成什么样的类,需要提供哪些信息由模板决定。提供信息的方式总是这样: 在模板名字后面跟一对尖括号,在括号内放上信息 。
以vector
为例,提供的额外信息是vector
内所存对象的类型:
vector<int> ivec;   // ivec保存int类型的对象
vector<Sales_item> Sales_vec;  // 保存Sales_item类型的对象
vector<vector<string>> file;  // 改向量的元素是vector对象
3.3.1 定义和初始化 vector 对象
初始化vector
对象的方法
以下是一些具体实例:
vector<int> ivec; // 默认初始化,不包含任何元素
vector<int> ivec2(ivec); // 把 ivec 的元素拷贝给 ivec2
vector<int> ivec3 = ivec; // 把 ivec 的元素拷贝给 ivec3
vector<string> svec(ivec2); // 错误:svec 和 ivec 元素类型不同,不能直接拷贝
列表初始化 vector 对象
用花括号括起来的 0 个或多个初始元素值进行列表初始化
vector<string> articles = {"a", "an", "the"};
大多数情况下初始化方式可以互相等价使用,但是有几种例外情况:
- 使用拷贝初始化时(即使用
=
时),只能提供一个初始值 - 如果提供的是一个类内初始值,则只能使用拷贝初始化或使用花括号的形式初始化
- 如果提供的是初始元素值的列表,则只能把初始值都放在花括号里进行列表初始化,而不能放在圆括号里
创建指定数量的元素
使用对象容纳的元素数量和所有元素的统一初始值来初始化vector
对象
vector<int> ivec(10, -1); // 10 个 int,每个都是 -1
vector<string> svec(10, "hi!"); // 10 个 string,每个都是 hi!
值初始化
可以只提供vector
对象容纳的元素数量而略去初始值,由库进行值初始化(value-initialized)的元素初值。
vector<int> ivec(10); // 10 个元素,每个都初始化为 0
vector<string> svec(10); // 10 个元素,每个都初始化为空 string
这种初始化方式有两个特殊限制:
- 有些类要求必须明确地提供初始值,如果
vector
对象中元素的类型不支持默认初始化,我们就必须提供初始的元素值; - 如果只提供了元素的数量而没有设定初始值,只能使用直接初始化。
列表初始值还是元素数量?
某些情况下,初始化的真实含义依赖于传递初始值用的是花括号还是圆括号。
vector<int> v1(10); // 10 个元素,默认初始为 0
vector<int> v2{10}; // 1 个元素, 值为 10
如果初始化时使用了花括号的形式但是提供的值又不能用来列表初始化,那么就会考虑用提供的值来构造vector
对象
vector<string> v3{10}; // 10 不能列表初始化 string,编译器构造含有 10 个元素的 vector
vector<string> v4("hello"); // 不能用字面值构建
vector<string> v5{"hello"}; // 1 个元素,初始值为 hello
vector<string> v3{10,"hello"}; // 10 不能列表初始化 string,编译器构造含有 10 个元素的 vector
3.3.2 向 vector 对象中添加元素
一般而言,直接初始化vector
对象的方式适用于三种情况:
- 初始值已知且数量较少;
- 初始值是另一个
vector
对象的副本; - 所有元素的初始值都一样
开始时创建空的vector
对象,在运行时使用成员函数push_back()
动态添加元素,是更通用的做法。
向 vector 对象添加元素蕴含的编程假定
必须要确保所写的循环正确无误。
3.3.3 其他 vector 操作
可以使用范围 for 语句处理vector
对象中的所有元素
vector<int> v1{1,2,3,4,5,6,7,8,9,10};
for(auto &i : v1)
i *= i;
for(auto &i : v1)
cout << i;
计算 vector 内对象的索引
使用下标运算符能获取到指定的元素。vector
对象的下标是从 0 开始,下标的类型是vector<T>::size_type
类型
不能使用下标形式添加元素
vector
对象(以及string
对象)的下标运算符可用于访问已存在的元素,而不能用于添加元素。
只能对确知已存在的元素执行下标操作!