Как пробежать по итератору или использование std::next
Есть std::vector<int> block.
И есть его перебор через итераторы:
for(auto iter=block->begin(); iter!=block->end(); iter++){
// Что-то делаем
// Получаем копию текущего итератора
auto startIter = iter;
int length = 0;
while (FindBlaBlaBla(*iter)){
auto stopIter = std::next(iter, length++);
}
// Что-то делаем
}
Вопросы:
- Можно ли вместо
std::nextзаписатьauto stopIter = iter + iter++;? - Что произойдет в момент
std::next(iter, 0)? - Что произойдет, если
std::next(iter, length), гдеiter + length > block->size()? - Можно ли заменить std::next() на что-то и какой в этом будет смысл?
P.S. Честно, не знаю, как назвать заголовок - если есть идеи получше - поправьте.
Ответы (2 шт):
0: Для vector<int> block вы не сможете написать block->begin(), только block.begin() - как и для end().
1: auto stopIter = iter + iter++; Так писать вообще не стоит - смешивать в одном выражении ++ с чем-то еще с той же переменной. Но все равно у вас ничего не получится, потому что это не скомпилируется - вы же хотели спросить о auto stopIter = iter + length++;? Да, для вектора - можно.
2: В момент next(iter, 0) произойдет вызов next(iter, 0). А после него iter не изменится, если вы об этом.
3: Произойдет undefined behavior.
4: Можно, например, на void advance(), но сюда итератор передается по ссылке и изменяется функцией.
С итераторами нельзя производить арифметические операции, что нельзя производить с указательями. Если следовать логике, то нужно себе спросить что будет означать iterator1 + iterator2 ? Каждый хранит адрес какого то элемента, и что получим суммируя эти адреса?... Если второй итератор смещен относительно первого на x элементов, то получается так:
iterator + x + iterator // нельзя
iterator + x - iterator == x //получаем смещение difference_type
- Т.е. разница итераторов, это логически нормальная операция, а сумма итераторов не входит в никакую логику, и итераторы имеют возможность выполнять первую операцию, если это итераторы произвольного доступа, а операции для суммы двух итераторов нет.
std::next(iter, 0)это то же самое, что иwhile(0) ++iter, т.е. ничего не произойдет.- Просто итератор укажет за конец последовательности. Такой итератор перестанет быть нужным для использования, кроме как получить значение насколько было смещение от конца.
- Смысль в том, что есть итераторы разной категории. Есть итераторы
однонаправленные(для чтения или для записи), двунаправленные(имеют операцию --) и произвольного доступа. Только итерторы произвольного доступа имеютoperator +. Чтобы получить итератор на n_тый элемент для, например,std::list, придетсяn раз выполнить ++iter, потому что итератор этого контейнера является однонаправленным, и у него нет operator+. Для того, чтобы каждый раз не писать цикл получения итератора, существуютstd::nextиstd::advance. Для итераторов произвольного доступа(например дляstd::vector::iterator iter) можно выполнитьiter += nвместо std::next(iter, n)