简体   繁体   中英

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() :

 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] . Why ? What the difference between the two ?

A std::vector is sequence container that encapsulates dynamic size arrays. 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.begin() is an iterator that starts at the beginning of the vector. 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. 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] . 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. The c++11 way has the additional benefit of also more clearly stating your intent to the people reading your code.

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

vec.begin() has type std::vector<int>::iterator . &vec[0] has type pointer to 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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