标准库类型 vector 表示对象的集合,其中所有对象的类型都相同。集合中每个对象都有与之对应的索引,索引用于访问对象。因为 vector "容纳着" 其他对象,所以也被称作容器。
vector 是模板类而非类型,由 vector 生成的类型必须包含 vector 中元素的类型,如:vector<int> v。
vector 能容容纳绝大多数类型的对象作为其元素,但因为引用不是对象,所以不存在包含引用的 vector。
定义和初始化 vector 对象:
1 vector<T> v1;//v1 是一个空 vector, 它潜在的元素是 T 类型的,执行默认初始化 2 3 vector<T> v2(v1);//v2 中包含 v1 中所有元素的副本 4 5 vector<T> v2 = v1;//等价于 v2(v1) 6 7 vector<T> v3(n, val);//v3包含了 n 个重复的元素,每个元素的值都是 val 8 9 vector<T> v4(n);//v4包含了 n 个重复执行了值初始化的对象 10 11 vector<T> v5{a, b, c...};//v5包含了初始值个数的元素,每个元素被赋予相应的初始值 12 13 vector<T> v5={a, b, c...};//等价于v5{a, b, c...}
一般情况下使用 "=" 的是拷贝初始化,使用 {} 的是列表初始化,而 () 提供的值是用来构造 vector 对象的。但是用 {} 和 () 区分列表初始化和构造初始化也并非绝对正确的。如果初始化时使用了花括号的形式但是提供的值又不能用来列表初始化,就要考虑用这样的值来构造 vector 对象了。如:
1 vector<string> v1{"em"};//列表初始化 2 3 vector<string> v2("em");//错误,不能使用字符面值构造vector对象 4 5 vector<string> v3{10};//v3有10个默认初始化的元素 6 7 vector<string> v4{10, "em"};//v4有10个值为"em"的元素
显然不能用 int 初始化 string 对象,所以 v3, v4提供的值不能用作元素的初始化,确认无法进行列表初始化后,编译器会尝试用默认值初始化 vector 对象,而 {} 提供的值则被用作构造 vector 对象。即对于 {} 提供的值编译器会优先尝试吃用列表初始化,失败后再尝试使用构造初始化。但是 () 提供的值只能用于构造 vector 对象而不能用作列表初始化。
像 vector 对象中添加元素:使用 push_back 成员函数
vector<int> v{1, 2};
v.push_back(1024);//1024被添加到 v 的尾部(2后面)
需要注意的是:如果循环体内部包含有向 vector 对象添加元素的语句,则不能使用范围 for 循环。
vector 支持的操作
1 v.empty();//如果v不含任何元素则返回true,否则返回false 2 3 v.size();//返回v中的元素个数 4 5 v.push_back(x);//向v尾部添加一个值为x的元素 6 7 v[n];//返回v中第n个元素的引用 8 9 v1 = v2;//使用v2中元素的拷贝替换v1中的元素 10 11 v = {a, b, c..};//使用列表中元素的拷贝替换v中的元素 12 13 v1 == v2;//返回true当且仅当v1和v2中的元素数量相同且对应位置的元素值都相同 14 15 v1 != v2;//与v1 == v2 相反 16 17 <, <=, >, >=;//以字典序比较两个vector对象
与string对象类似,使用范围for循环改变vector对象的值要用引用
1 vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9}; 2 3 for(auto &indx : v){ 4 5 indx *= indx; 6 7 }