2015-04-30 3 views
1

У меня есть функция, которая выполняет итерацию через вектор и вызывает другую функцию, чтобы каким-то образом выполнить ее содержимое. В результате этого выполнения к вектору могут быть добавлены новые элементы. Код функции выглядит следующим образом:Расширение вектора во время итерации через него

void foo() { 
    for (std::vector<Item*>::iterator it = item_list.begin(); it != item_list.end(); ++it) { 
     if (/*some condition*/) { 
      bar(it); 
     } 
    } 
} 

В то время как я был прибегая к помощи этой проблемы, я увидел, что итератор может получить недействительным, если изменение размера происходит, но автор не конкретно о том, почему ни когда и что правильный способ обращения Эта проблема.

+1

Ваш образец не представляет проблемы. –

+0

@ DieterLücking: 'item_list' может быть глобальным, который модифицируется' bar', но вы правы, что неясно, имеет ли образец проблему, и ее необходимо уточнить. –

+0

Ваш вопрос довольно расплывчатый. Где добавляются новые предметы? В начало/конец/в любом месте вектора? Если они добавлены до текущего итератора, вы в порядке с циклом 'for', не перебирая их? – Praetorian

ответ

2

Как вектор произвольный доступ, вы можете сохранить расстояние временно и заново создать итератор впоследствии:

void foo() { 
    for (std::vector<Item*>::iterator it = item_list.begin(); it != item_list.end(); ++it) { 
     if (/*some condition*/) { 
      const auto d = std::distance(item_list.begin(), it); 
      bar(it); 
      it = item_list.begin(); 
      std::advance(it, d); 
     } 
    } 
} 

Ответ предполагает, что новые элементы добавляются после текущей позиции, например, в конец. Он также предполагает, что желательно, чтобы новые элементы также были частью итерации, т. Е. Они также будут проверяться на some condition, а bar будет вызываться, если они совпадают.

+0

Спасибо, что именно мне нужно. – user100593

+0

Просто используйте список! (Конечно, я предполагаю, что случайный доступ не нужен) – Throwback1986

+0

@ Throwback1986 Это решение будет иметь последствия для производительности, вы не можете предположить, что общая эффективность OPs выиграет от этого. –

0

Вместо того, чтобы вставлять больше элементов в этот вектор во взаимодействии, просто создайте еще один вектор для хранения всех элементов и выполните изменение размера при повторении в этом случае, затем вы отбросите текущий и замените этот обновленный вектор.

Это стандартный способ сделать это.

1

В соответствии с documentation, если вставка элемента меняет емкость vector, все итераторы являются недействительными.

Чтобы обойти это, добавьте новые элементы во временный vector и объедините их после того, как все будет готово.

Смежные вопросы