C++中的vector

opencv中用到了很多vector  整理一下

vector容器是一个模板类,可以存放任何类型的对象(但必须是同一类对象)。vector对象可以在运行时高效地添加元素,并且vector中元素是连续存储的。

vector容器内存放的所有对象都是经过初始化的。如果没有指定存储对象的初始值,那么对于内置类型将用0初始化,对于类类型将调用其默认构造函数进行初始化(如果有其它构造函数而没有默认构造函数,那么此时必须提供元素初始值才能放入容器中)。
 
简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。

1、vector对象的定义和初始化

使用vector之前,必须包含相应的头文件。
#include <vector>
using std::vector;
(1)vector< 类型 > 标识符 ;
vector<T> v1 vector保存类型为T的对象。默认构造函数,v1为空 (2)vector< 类型 > 标识符(最大容量) ;
vector<T> v2(n) (3)vector< 类型 > 标识符(最大容量,初始所有值);
vector<T> v3(n,i) v3包含n个值为i的元素

当把一个vector对象复制到另一个vector对象时,新复制的vector中每一个元素都初始化为原vector中相应元素的副本。但这两个vector对象必须保存同一种元素类型:

vector<int> ivec1;                // ivec1 holds objects of type int

vector<int> ivec2(ivec1);       // ok: copy elements of ivec1 into ivec2

vector对象(以及其他标准库容器对象)的重要属性就在于可以在运行时高效地添加元素。
虽然可以对给定元素个数的vector对象预先分配内存,但更有效的方法是先初始化一个空vector对象,然后再动态地增加元素。
 

如果没有给出元素的初始化式,那么标准库将提供一个值初始化的(value initialized)元素初始化式。这个由库生成的初始值用于初始化容器中的每个元素。而元素初始化式的值取决于存储在vector中元素的数据类型。

如果vector保存内置类型(如int类型)的元素,那么标准库将用0值创建元素初始化值:

vector<int> fvec(10); // 10 elements, each initialized to 0

如果向量保存类类型(如string)的元素,标准库将用该类型的默认构造函数创建元素初始值:

vector<string> svec(10); // 10 elements, each an empty string

总结:
对内置类型,值为0
对类类型,使用默认初始化
 

2、花括号,圆括号区别

vector<int> v1(); // 10个元素,都是0
vector<int> v1{}; // 1个元素,是10
vector<int> v1{, }; // 2个元素,分别是10, 1
vector<int> v1(, ); // 10个元素,都是1

{}并不一定就是列表初始化;它表示: 如果可能的话,使用列表初始化

vector<string> v5{"hi"}; // ok, list initialization
vector<string> v6("hi"); // error: cann't construct vector from string lieral
vector<string> v7{}; // has ten default-initialized value

上面的v7就使用花括号指定个数,而不是列表初始化。

3、vector的操作

v.empty()

如果v为空,则返回true,否则返回false。

v.size()

返回v中元素的个数。

v.push_back(t)

在v的末尾增加一个值为t的元素。

v[n]

返回v中位置为n的元素。

v1 = v2

把v1的元素替换为v2中元素的副本。

v1 == v2

如果v1与v2相等,则返回true。

!=, <, <=, >, >=

保持这些操作符惯有的含义。

vector添加元素

push_back()操作接受一个元素值,并将它作为一个新的元素添加到vector对象的后面,也就是“插入(push)”到vector对象的“后面(back)”:

 vector< int > vi ;
vi.push_back();
vi.push_back();

vector的下标操作

vector中的对象是没有命名的,可以按vector中对象的位置来访问它们。通常使用下标操作符来获取元素。vector的下标操作类似于string类型的下标操作。

vector的下标操作符接受一个值,并返回vector中该对应位置的元素。vector元素的位置从0开始。下例使用for循环把vector中的每个元素值都重置为0:

reset the elements in the vector to zero

for (vector<int>::size_type ix = 0; ix != ivec.size(); ++ix)

    ivec[ix] = 0;

和string类型的下标操作符一样,vector下标操作的结果为左值,因此可以像循环体中所做的那样实现写入。另外,和string对象的下标操作类似,这里用size_type类型作为vector下标的类型。

上例中,即使ivec为空,for循环也会正确执行。ivec为空则调用size返回0,并且for中的测试比较ix和0。第一次循环时,由于ix本身就是0,则条件测试失败,for循环体一次也不执行。

下标操作不添加元素

初学C++的程序员可能会认为vector的下标操作可以添加元素,其实不然:

vector<int> ivec;   // empty vector

for (vector<int>::size_type ix = 0; ix != 10; ++ix)

     ivec[ix] = ix; // disaster: ivec has no elements

  

这个循环的正确写法应该是:

for (vector<int>::size_type ix = 0; ix != 10; ++ix)

     ivec.push_back(ix);  // ok: adds new element with value ix

  必须是已存在的元素才能用下标操作符进行索引。通过下标操作进行赋值时,不会添加任何元素。

 警告:仅能对确知已存在的元素进行下标操作   

对于下标操作符([]操作符)的使用有一点非常重要,就是仅能提取确实已存在的元素,例如:

vector<int> ivec;      // empty vector

cout << ivec[];        // Error: ivec has no elements!

vector<int> ivec2(); // vector with 10 elements

cout << ivec[];      // Error: ivec has elements 0...9

http://www.jb51.net/article/83998.htm

http://www.cppblog.com/totti1006/archive/2009/09/01/94955.html
《C++ Primer中文版》
上一篇:【论文笔记】AffinityNet Semi-supervised few-shot learning for disease type prediction


下一篇:attention is all you need笔记