Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;STL:当需要访问元素及其索引时,如何迭代向量?_C++_Stl_Vector_Iteration - Fatal编程技术网

C++ C++;STL:当需要访问元素及其索引时,如何迭代向量?

C++ C++;STL:当需要访问元素及其索引时,如何迭代向量?,c++,stl,vector,iteration,C++,Stl,Vector,Iteration,我经常发现自己需要迭代STL向量。执行此操作时,我需要访问向量元素及其索引 我以前是这样做的: typedef std::vector<Foo> FooVec; typedef FooVec::iterator FooVecIter; FooVec fooVec; int index = 0; for (FooVecIter i = fooVec.begin(); i != fooVec.end(); ++i, ++index) { Foo& foo = *i;

我经常发现自己需要迭代STL向量。执行此操作时,我需要访问向量元素及其索引

我以前是这样做的:

typedef std::vector<Foo> FooVec;
typedef FooVec::iterator FooVecIter;

FooVec fooVec;
int index = 0;
for (FooVecIter i = fooVec.begin(); i != fooVec.end(); ++i, ++index)
{
    Foo& foo = *i;
    if (foo.somethingIsTrue()) // True for most elements
        std::cout << index << ": " << foo << std::endl;
}
typedef std::vector FooVec;
typedef FooVec::迭代器fooviter;
FooVec FooVec;
int指数=0;
for(FooVecIter i=fooVec.begin();i!=fooVec.end();++i,++index)
{
Foo&Foo=*i;
if(foo.somethingIsTrue())//对于大多数元素为True
std::cout
for(size_t i=0;i

向量是C数组上的一个薄包装器;无论您使用迭代器还是索引,它都一样快。不过,其他数据结构并不是那么容易理解,例如std::list。

您始终可以在循环中计算索引:

std::size_t index = std::distance(fooVec.begin(), i);

对于一个向量,这很可能被实现为一个单指针减法运算,因此它并不特别昂贵。

优雅是旁观者的眼睛,但是请记住指针/迭代器算法:)

for(FooVecIter i=fooVec.begin();i!=fooVec.end();++i)
{
Foo&Foo=*i;
if(foo.somethingIsTrue())//对于大多数元素为True

std::cout对于具体问题:

伊姆霍

for(size_t i=0;i

是最简单、最优雅的解决方案。根据问题的要求,不需要使用迭代器。

但是,对于其他数据结构,它可能会变得非常昂贵。@iconiK:我不同意这一点。我认为如果迭代泛型容器的所有元素,最好在循环中增加索引。这样,您就可以在计算索引时,不要在列表中循环300万次。@iconiK:通过下标访问元素不应该比计算从容器开始到给定迭代器的距离快。可能会有一些极端情况,但我想不出有任何异常情况。
std::distance
对于像这样的随机访问迭代器
std::vector
是O(1),它只是一个指针减法,但对于其他不太灵活的迭代器(例如
std::list
的迭代器),它是一个O(N)操作,最好不要在循环中反复计算
index
。为什么在i-fooVec.begin()中从Foo中减去foovciter//没有任何意义。好吧,它可以工作,尽管我不知道具体是如何工作的,因为它很奇怪(但我不是迭代器向导):@iconiK,两者都是FooVectIter@Kornel:我同意;强制迭代器是随机可访问的通常比使用距离更好。@Kornel,啊,我的错,我以为我看到了foo-fooVec.begin(0).我告诉你,疲劳不利于编程!事实上,这并不一定是最好的。随机访问比迭代更不容易进行缓存优化——迭代携带了额外的信息,即数据将按顺序访问,这使现代优化器能够准备缓存并将我们从如此昂贵的缓存管理信息系统中解救出来在不同的架构上运行一个比较非平凡向量迭代的测试——您可能会感到惊讶。这很有趣,但您能提供一个源(链接或关键字)吗?哪种编译器是这样的?一般来说,识别循环中的顺序访问对编译器来说应该不会比识别std迭代器更难。我可以想出几个其他原因来解释为什么迭代会更快,这取决于向量实现。事实上,我刚刚查阅了英特尔编译器文档,其中列出了大量cac他访问了循环的优化,没有一次提到(以任何名义)迭代的stl风格。在最佳情况下,stl迭代将优化为循环,然后应用相同的技术。实际上,假设使用迭代器进行顺序访问是不可能的,因为我可以使用随机访问迭代器轻松地前进任意数量的元素。它不比索引更具优化性;向量迭代器是可行的ally是一个普通指针。无论您是在每次迭代中递增指针还是在其中添加i,它仍然是一个简单的add指令。您不能重新绑定引用。
for (size_t i = 0; i < vec.size(); i++)
    elem = vec[i];
std::size_t index = std::distance(fooVec.begin(), i);
for (FooVecIter i = fooVec.begin(); i != fooVec.end(); ++i)
{
    Foo& foo = *i;
    if (foo.somethingIsTrue()) // True for most elements
        std::cout << i - fooVec.begin() << ": " << foo << std::endl;
}
Is there a better or more elegant way to iterate over STL vectors
when both reference to the vector element and its index is required?
for (size_t i = 0; i < fooVec.size(); ++i) {
    Foo & foo = fooVec[i];        // if 'foo' is to be modified
    Foo const& foo = fooVec[i];   // if 'foo' is to be NOT modified
}