我有一个看起来像这样的函数:
void myclass::myfunc()
{
int i;
for( std::vector<Foo>::iterator it = var.begin(), i = 0; it < var.end(); it++, i++ )
{
/* ... */
}
}
我收到了这个错误:
无法从
int
转换为std::_Vector_iterator<>
此代码有什么问题?
答案 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;
}