|
|||||||||||||
|
Section 34:
|
[34.3] Is the storage for a std::vector<T> guaranteed to be contiguous?
Yes. This means the following technique is safe:
#include <vector>
#include "Foo.h" /* get class Foo */
// old-style code that wants an array
void f(Foo* array, unsigned numFoos);
void g()
{
std::vector<Foo> v;
...
f(v.empty() ? NULL : &v[0], v.size()); ← safe
}
The funny expression v.empty() ? NULL : &v[0] simply passes the
NULL pointer if v is empty, otherwise passes a pointer to the
first (zeroth) element of v. If you know a priori that
v is not empty, you can change that to simply &v[0].
In general, it means you are guaranteed that &v[0] + n == &v[n], where v is a std::vector<T> and n is an integer in the range 0 .. v.size()-1. However v.begin() is not guaranteed to be a T*, which means v.begin() is not guaranteed to be the same as &v[0]:
void g()
{
std::vector<Foo> v;
...
f(v.begin(), v.size()); ← Error!! Not Guaranteed!!
^^^^^^^^^-- cough, choke, gag; not guaranteed to be the same as &v[0]
}
Do NOT email me and tell me that v.begin() ==
&v[0] on your particular version of your particular compiler on your
particular platform. I don't care, plus that would show that you've
totally missed the point. The point is to help you know the kind of
code that is guaranteed to work correctly on all standard-conforming
implementations, not to study the vagaries of particular implementations.
|
||||||||||||