C++向量迭代器与指针

dgm*_*ulf 13 c++ pointers iterator vector

有很多替代方法来处理向量的元素.

我可以像这样使用指针:

vector<int> v = {10, 11, 12};
int *p = &v[0];
cout << *p;    //Outputs "10"
Run Code Online (Sandbox Code Playgroud)

我也可以这样使用指针:

vector<int> v = {10, 11, 12};
vector<int>::pointer p = v.data();
cout << *p;    //Outputs "10"
Run Code Online (Sandbox Code Playgroud)

我也可以使用迭代器类型:

vector<int> v = {10, 11, 12};
vector<int>::iterator i = v.begin();
cout << *i;    //Outputs "10"
Run Code Online (Sandbox Code Playgroud)

我在这里缺少哪些重大差异?

Jos*_*eld 6

就能够执行手头的任务而言,它们都工作良好。毕竟,它们都提供了一个满足迭代器要求的对象,并且您正在使用它们指向的相同元素vector但是,我会选择该vector<int>::iterator选项,因为该类型更能表达我们打算如何使用它。

原始指针类型int*告诉您什么p是什么,除了它存储的地址外int。如果您p孤立地考虑,它的类型并不能告诉您如何使用它。该vector<int>::pointer选项具有相同的问题-它只是将其指向的对象的类型表示为向量的元素类型。它实际上没有必要指向vector

另一方面vector<int>::iterator告诉您所有您需要知道的内容。它明确指出该对象是一个迭代器,并且该迭代器用于指向.NET中的元素vector<int>

如果碰巧更改了容器类型,这还具有易于维护的优点。std::list例如,如果更改为,则指针类型将不再起作用,因为元素未存储为连续数组。iterator容器的类型始终为您提供一种可用于迭代其元素的类型。


当我们有了Concepts时,我希望最佳实践是这样的:

ForwardIteratorOf<int> it = std::begin(v);
Run Code Online (Sandbox Code Playgroud)

其中,ForwardIteratorOf<int>(这我想象的存在)改为无论概念最能描述你的意图了it。如果元素的类型并不重要,那么就ForwardIterator(或BidirectionalIteratorRandomAccessIterator或其他)。

  • 只是一个小小的评论:我希望 `auto` 仍然是首选。此外,您可能想补充一点,`vector&lt;int&gt;::iterator` 和 `int*` 在发布配置中很可能是相同的。 (3认同)

Ulr*_*rdt 1

所有这些方式都有其优点,但本质上它们非常相似。当向量为空时,其中一些不起作用(它们会导致所谓的“未定义行为”)。