Ответ 1
Вы можете сделать это следующим образом:
int i = 0;
for( std::vector<int>::iterator it = v.begin(); it < v.end(); ++it, ++i){}
У меня есть функция, которая выглядит так:
void myclass::myfunc()
{
int i;
for( std::vector<Foo>::iterator it = var.begin(), i = 0; it < var.end(); it++, i++ )
{
/* ... */
}
}
Я получаю эту ошибку:
Невозможно преобразовать из
int
вstd::_Vector_iterator<>
Что не так с этим кодом?
Вы можете сделать это следующим образом:
int i = 0;
for( std::vector<int>::iterator it = v.begin(); it < v.end(); ++it, ++i){}
Проблема заключается в этой части цикла for
:
std::vector<Foo>::iterator it = var.begin(), i = 0
С++ интерпретирует это не как два оператора, разделенных запятыми, а как объявление переменной для переменной с именем 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++ )
{
// ...
}
Тем не менее, существует один последний вариант. Если вам нужно отслеживать индекс в векторе, который вы сейчас просматриваете, вы можете просто использовать подсчет для цикла (без итератора) или использовать только итератор и использовать вычитание итератора для восстановления индекса:
for (auto it = var.begin(); it != var.end(); ++it) {
// current position is it - var.begin();
}
Надеюсь, это поможет!
Избавьтесь от части 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
.
В зависимости от того, что в теле цикла, вы, вероятно, хотите полностью избавиться от цикла и заменить его алгоритмом.
Двойная итерация:
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;
}
Вам нужно прочитать оператор запятой.
Вопрос Как работает оператор Comma Operator даст вам некоторую информацию о поведении, которое вы получаете.