这个问题与 Effective stl book 的第 16 条有关,它指出,vector<int>vec在遗留代码中使用 vector(lets假设)而不是数组时,我们必须使用 &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???
Run Code Online (Sandbox Code Playgroud)
该书指出,这vec.begin()与&vec[0]. 为什么 ?两者有什么区别?
std ::vector是封装动态大小数组的序列容器。这使您可以方便地存储一堆元素,而无需关心管理存储元素的底层数组。使用这些类的便利很大程度上来自于这样一个事实:它们为您提供了一堆方法,让您无需处理原始指针即可处理序列,迭代器就是一个例子。
&vec[0]是指向向量正在使用的底层存储的第一个元素的指针。vec.begin()是一个从向量开头开始的迭代器。虽然这两种方法都为您提供了访问序列中元素的方法,但它们是两个不同的概念。搜索迭代器以更好地了解其工作原理。
如果您的代码支持迭代器,那么使用迭代器迭代数据通常是最简单的。造成这种情况的部分原因是迭代器不是指针,它们使您可以迭代数据结构的元素,而无需了解要迭代的数据结构的实现细节。
然而,有时您需要原始项目数组,例如在某些旧版 API 或对 C 代码的调用中,您可能需要传递指向数组的指针。在这种情况下,您别无选择,只能从向量中提取原始数组,您可以使用诸如&vec[0]. 请注意,如果您有 c++11 支持,则有一种明确的方法可以执行此操作std::vector::data,使您可以访问底层存储数组。c++11 方式还有一个额外的好处,即可以更清楚地向阅读代码的人说明您的意图。