如何编写一个使用迭代器和索引计数器的for循环?

时间:2013-06-10 03:07:11

标签: c++ for-loop stl

我有一个看起来像这样的函数:

void myclass::myfunc()
{
    int i;
    for( std::vector<Foo>::iterator it = var.begin(), i = 0; it < var.end(); it++, i++ )
    {
        /* ... */
    }
}

我收到了这个错误:

  

无法从int转换为std::_Vector_iterator<>

此代码有什么问题?

4 个答案:

答案 0 :(得分:19)

问题出在for循环的这一部分:

std::vector<Foo>::iterator it = var.begin(), i = 0

C ++不是将它解释为两个以逗号分隔的语句,而是作为一个名为it的变量的变量声明,它是一个迭代器,并作为变量i的新声明,它是一个迭代器,初始化为0.错误是因为您无法将vector迭代器初始化为0。

要解决此问题,您需要在循环之外提升定义:

int i = 0;
std::vector<Foo>::iterator it = var.begin();
for(; it < var.end(); it++, i++ )
{
     // ...
}

或者将i的初始化移到循环之外:

int i = 0;
for( std::vector<Foo>::iterator it = var.begin(); it < var.end(); it++, i++ )
{
    // ...
}

但是还有最后一个选择。如果你需要跟踪你正在查看的向量中的索引,你可以考虑只使用count for循环(没有迭代器),或者只使用迭代器并使用迭代器减法来恢复索引:

for (auto it = var.begin(); it != var.end(); ++it) {
    // current position is it - var.begin();
}

希望这有帮助!

答案 1 :(得分:11)

你可以这样做:

int i = 0;
for( std::vector<int>::iterator it = v.begin(); it < v.end(); ++it, ++i){}

答案 2 :(得分:2)

摆脱i=0;部分(至少在循环标题内)。

另外,如果您坚持这样做,请考虑使用:

for (auto it : var)

或:

for (auto it = var.begin(); it != var.end(); ++it)

...来代替。由于您无论如何都在使用随机访问迭代器,因此i所拥有的内容相当于it - var.begin()。相反,你可以使用:

for (int i=0; i<var.size(); i++)

...并在需要时获得一个迭代器var.begin() + i

根据循环体中的内容,您可能希望完全摆脱循环,然后用算法替换它。

答案 3 :(得分:1)

双重迭代:

using std::begin; using std::end;
for (auto p = std::make_pair( begin(var), 0 ); p.first != end(var); ++p.first, ++p.second ) {
  /* ... */
}

使用命名索引/迭代器进行双重迭代:

using std::begin; using std::end;
int i;
std::vector<Foo>::iterator it;
for (std::tie( it, i ) = std::make_pair( begin(var), 0 ); it != end(var); ++it, ++i ) {
  /* ... */
}

或在每次迭代时将上述对绑定到更好的命名变量:

using std::begin; using std::end;
for (auto p = std::make_pair( begin(var), 0 ); p.first != end(var); ++p.first, ++p.second ) {
  auto const& it = p.first;
  int i = p.second;
}