& vector [0]和vector.begin()之间有什么区别?

时间:2015-05-28 15:24:28

标签: c++ vector

这个问题与有效stl书的第16项有关,它指出虽然在遗留代码中使用vector(让我们假设vector<int>vec)而不是数组,我们必须使用&amp; vec [0]而不是vec.begin ():

 void doSomething(const int* pInts, size_t numlnts);  
 dosomething(&vec[0],vec.size()); \\correct!! 
 dosomething(vec.begin(),vec.size()); \\ wrong!! why??? 

该书指出vec.begin()&vec[0]不同。为什么?两者有什么区别?

3 个答案:

答案 0 :(得分:3)

std::vector是封装动态大小数组的序列容器。这使您可以方便地存储一堆元素,而无需关心管理作为元素存储的底层数组。使用这些类的大部分方便来自于它们为您提供了一系列方法,可以让您处理序列而无需处理原始指针,迭代器就是一个例子。

&vec[0]是指向矢量正在使用的底层存储的第一个元素的指针。 vec.begin()iterator,它始于向量的开头。虽然这两种方法都为您提供了访问序列中元素的方法,但这些是两个截然不同的概念。搜索迭代器以更好地了解其工作原理。

如果您的代码支持iterators,则通常最容易使用迭代器迭代数据。部分原因是迭代器不是指针,它们允许您迭代数据结构的元素,而无需了解您正在迭代的数据结构的实现细节。< / p>

但是,有时您需要原始数组项,例如在某些遗留API或调用C代码时,您可能需要将指针传递给数组。在这种情况下,您别无选择,只能从向量中提取原始数组,您可以使用&vec[0]之类的内容来完成此操作。请注意,如果您具有c ++ 11支持,则可以使用std::vector::data明确地执行此操作,这将使您可以访问底层存储阵列。 c ++ 11方式还有一个额外的好处,就是更清楚地说明你对阅读代码的人的意图。

答案 1 :(得分:3)

形式上,一个产生迭代器,另一个产生指针,但我认为主要区别在于vec[0]如果向量为空则会做坏事,而vec.begin()则不会。

答案 2 :(得分:3)

vec.begin()的类型为std::vector<int>::iterator&vec[0]具有指向std::vector<int>::value_type的类型指针。这些不一定是同一类型。

给定的实现可能使用指针作为向量的迭代器实现,但这不能保证,因此您不应该依赖于该假设。实际上,大多数实现都提供了包装迭代器类型。

关于指针作为迭代器的问题,这部分是正确的。指针确实符合随机访问迭代器的标准,但并非所有迭代器都是指针。并且有些迭代器不支持指针的随机访问行为。

相关问题