#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()
бы, что значение никогда не меняется.