我有一个看起来像这样的函数:
void myclass::myfunc()
{
int i;
for( std::vector<Foo>::iterator it = var.begin(), i = 0; it < var.end(); it++, i++ )
{
/* ... */
}
}
我收到此错误:
无法转换
int
为std::_Vector_iterator<>
这段代码有什么问题?
问题在于for
循环的这一部分:
std::vector<Foo>::iterator it = var.begin(), i = 0
C++ 不是将其解释为两个逗号分隔的语句,而是将其解释为名为it
iterator 的变量的变量声明,以及作为迭代器并初始化为 0 的变量的新声明。i
错误是因为您无法初始化一个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++ )
{
// ...
}
这是另一种选择。如果您需要跟踪当前正在查看的向量的索引,您可以考虑仅使用计数循环(不使用迭代器),或者仅使用迭代器并使用迭代器减法来恢复索引:
for (auto it = var.begin(); it != var.end(); ++it) {
// current position is it - var.begin();
}
for
最后,如果你有一个兼容 C++20 的编译器,你可以完全消除迭代器并通过以下方式使用增强循环:
/* Requires C++20 */
for (int i = 0; Foo f: var) {
/* Do something worthwhile with f. */
i++;
}
希望这可以帮助!
你可以这样做:
int i = 0;
for( std::vector<int>::iterator it = v.begin(); it < v.end(); ++it, ++i){}
摆脱i=0;
部分(至少在循环标题内)。
此外,如果您坚持这样做,请考虑使用:
for (auto it : var)
或者:
for (auto it = var.begin(); it != var.end(); ++it)
...反而。由于无论如何您都在使用随机访问迭代器,因此您所拥有的 asi
相当于it - var.begin()
. 相反,您可以只使用:
for (int i=0; i<var.size(); i++)
...并在需要时获取迭代器作为var.begin() + i
.
根据循环体中的内容,您可能希望完全摆脱循环,并用算法替换它。
双迭代:
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;
}