Гарантируется ли для(авто …) списка, в который мы добавляем новые элементы в цикле, работа со всеми элементами?

#c #list #for-loop #linked-list #stl

Вопрос:

У меня есть класс с f_next полем, которое выглядит так:

 class process
{
public:
    typedef std::shared_ptr<process> pointer_t;
    typedef std::list<pointer_t> list_t;

    void add_next_process(pointer_t p);
    void wait();

private:
    list_t f_next = list_t();
};
 

add_next_process() Просто добавляется к p f_next :

 f_next.push_back(p);
 

В результате wait() приходится собирать все процессы и ждать их всех. Я бы хотел избежать рекурсии и вместо этого сгенерировать список всего f_next подобного, так что:

 list_t n(f_next);
for(auto amp; it : n)
{
    n.insert(n.end(), it->f_next.begin(), it->f_next.end());
}
 

n Гарантируется ли включение всех элементов после завершения for() цикла?

Я знаю, что std::list::insert() это не меняет итератор:

Никакие итераторы или ссылки не являются недействительными.

но мне интересно, будет ли for(auto ...) продолжаться просмотр всех пунктов, которые я добавил по пути.

Комментарии:

1. Я обнаружил, что в целом изменение контейнера или содержимого контейнера при повторном просмотре-это обильный источник ошибок и проблем с обслуживанием. На порядок больше, если исключения находятся в смеси, пытаясь при этом сохранить согласованность и инварианты.

Ответ №1:

For-range-это просто синтаксический сахар для классического цикла for, работающего на итераторах. Пока ваш контейнер реализует начало и конец (или у вас есть свободные перегрузки) и не делает итератор недействительным в процессе, технически это должно быть нормально. Другое дело, является ли это хорошей и поддерживаемой идеей.

До C 17:

 auto amp;amp; __range = range-expression ;
for (auto __begin = begin_expr, __end = end_expr; __begin != __end;   __begin) {
  range-declaration = *__begin;
  loop-statement
}
 

Из C 17:

 auto amp;amp; __range = range-expression ;
auto __begin = begin_expr ;
auto __end = end_expr ;
for ( ; __begin != __end;   __begin) {
  range-declaration = *__begin;
  loop-statement
}
 

Комментарии:

1. Круто. Это означало std::list::end() бы, что значение никогда не меняется.