When you want access a std::vector as a C array you can choose from at least four different ways, as you can see in this example:
#include <iostream>
#include <vector>
using namespace std;
int main() {
std::vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(42);
vec.push_back(24024);
{
int* arr = vec.data();
cout << arr << endl; /* output: 0x9bca028 */
cout << arr[3] << endl; /* output : 24024 */
}
{
int* arr = &vec.front();
cout << arr << endl; /* output: 0x9bca028 */
cout << arr[3] << endl; /* output : 24024 */
}
{
int* arr = &vec[0];
cout << arr << endl; /* output: 0x9bca028 */
cout << arr[3] << endl; /* output : 24024 */
}
{
int* arr = &vec.at(0);
cout << arr << endl; /* output: 0x9bca028 */
cout << arr[3] << endl; /* output : 24024 */
}
}
The one I've found in most cases is the &vec[0]
. I think it's the least elegant, so... why is it the most used? Is it more efficient or more compatible? I can't find lot of documentation about data()
.
data()
is brand new to C++11, that's why you don't see it as often. The idea of using &vec.front()
never even occurred to me, probably because I use operator[]
alot more often than front()
(almost never). I imagine it's the same for other people.
If you're using C++11, then using data()
is definitely preferable. In particular, if the vector is empty, then using either of the other two options yields undefined behavior! If you're not using C++11, and the vector may be empty, then be sure to check that condition.
Using &vec[0] is the most common although, I agree, does look a little odd. One thing to keep in mind for the future. If your vector happens to be a vector of objects whose class overloads the operator&(), realize that this will cause strange behavior if you call &vec[0].
This will not get the starting address of the first item in the internal contiguous array of objects, it will return whatever vec[0].operator&() would return. Most if not all of the time, that's not the address you're looking for (Jedi hand wave).
A good example of this is ATL's CComPtr. It overloads operator&() so storing it in a vector can be problematic. To get around this, ATL has a CAdapt template class which can be used to hide the operator&() on CComPtr
Before C++11's std::array
I would say that std::vector
was the most common container to be used instead of the C-style array. The []
operator usually implies constant time access, (which is what std::vector
is all about), and so most coders usually choose this style to reflect array-like access and behavior.
data() has been part of std::string
for some time now so you might read-up on that. I've found the data() implementation in std::vector
to be similar. I occasionally use data() to treat a std::string
as an array of raw bytes.