简体   繁体   English

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

[英]What is the difference between &vector[0] and vector.begin()?

This question is related with item 16 of effective stl book which states that while using vector(lets assume vector<int>vec ) instead of array in a legacy code we must use &vec[0] instead of vec.begin() :这个问题与 Effective stl book 的第 16 条有关,它指出在遗留代码中使用 vector(让我们假设vector<int>vec )而不是数组时,我们必须使用 &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??? 

The book states that vec.begin() is not same as &vec[0] .这本书指出vec.begin()&vec[0] Why ?为什么 ? What the difference between the two ?两者有什么区别?

A std::vector is sequence container that encapsulates dynamic size arrays. std::vector是封装动态大小数组的序列容器。 This lets you conveniently store a bunch of elements without needing to be as concerned with managing the underlying array that is the storage for your elements.这使您可以方便地存储一堆元素,而无需担心管理作为元素存储的底层数组。 A large part of the convenience of using these classes comes from the fact that they give you a bunch of methods that let you deal with the sequence without needing to deal with raw pointers, an iterator is an example of this.使用这些类的很大一部分便利来自于它们为您提供了一堆方法,让您无需处理原始指针即可处理序列,迭代器就是一个例子。

&vec[0] is a pointer to the first element of the underlying storage that the vector is using. &vec[0]是指向向量正在使用的底层存储的第一个元素的指针。 vec.begin() is an iterator that starts at the beginning of the vector. vec.begin()是一个从向量开头开始的迭代器 While both of these give you a way to access the elements in the sequence these are 2 distinct concepts.虽然这两种方法都为您提供了一种访问序列中元素的方法,但它们是两个不同的概念。 Search up iterators to get a better idea of how this works.搜索迭代器以更好地了解其工作原理。

If your code supports iterators its often easiest to use the iterators to iterate over the data.如果您的代码支持迭代器,通常最容易使用迭代器来迭代数据。 Part of the reasons for this is that iterators are not pointers , they let you iterate over the elements of the data structure without needing to know as much about the implementation details of the datastructure you are iterating over.部分原因是迭代器不是指针,它们让您迭代数据结构的元素,而无需了解您正在迭代的数据结构的实现细节。

However sometimes you need the raw array of items, for example in some legacy API's or calls to C code you might need to pass a pointer to the array.但是,有时您需要原始的项目数组,例如在某些遗留 API 或对 C 代码的调用中,您可能需要传递指向该数组的指针。 In this case you have no choice but to extract the raw array from the vector, you can do this using something such as &vec[0] .在这种情况下,您别无选择,只能从向量中提取原始数组,您可以使用诸如&vec[0]东西来执行此操作。 Note that if you have c++11 support there's an explicit way to do this with std::vector::data which will give you access to the underlying storage array.请注意,如果您有 c++11 支持,则有一种明确的方法可以使用std::vector::data执行此操作,这将使您可以访问底层存储阵列。 The c++11 way has the additional benefit of also more clearly stating your intent to the people reading your code. c++11 方式还有一个额外的好处,那就是更清楚地向阅读你代码的人说明你的意图。

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

vec.begin() has type std::vector<int>::iterator . vec.begin()类型为std::vector<int>::iterator &vec[0] has type pointer to std::vector<int>::value_type . &vec[0]具有指向std::vector<int>::value_type类型指针。 These are not necessarily the same type.这些不一定是相同的类型。

It is possible that a given implementation uses pointers as the iterator implementation for a vector, but this is not guaranteed, and thus you should not rely on that assumption.给定的实现可能使用指针作为向量的迭代器实现,但这不能保证,因此您不应依赖该假设。 In fact most implementations do provide a wrapping iterator type.事实上,大多数实现确实提供了一个包装迭代器类型。

Regarding your question about pointers being iterators, this is partly true.关于您关于指针是迭代器的问题,这在一定程度上是正确的。 Pointers do meet the criteria of a random access iterator, but not all iterators are pointers.指针确实满足随机访问迭代器的标准,但并非所有迭代器都是指针。 And there are iterators that do not support the random access behavior of pointers.还有一些迭代器不支持指针的随机访问行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM