Home > Back-end >  Is a for(auto ...) of list where we append new elements within the loop guaranteed to work against a
Is a for(auto ...) of list where we append new elements within the loop guaranteed to work against a

Time:09-21

I have a class with an f_next field that looks like so:

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();
};

The add_next_process() simply appends p to f_next:

f_next.push_back(p);

As a result, the wait() has to gather all the processes and wait for all of them. I'd like to avoid recursion and instead generate a list of all the f_next like so:

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

Is n guaranteed to include all the items once the for() loop exits?

I know that std::list::insert() does not change the iterator:

No iterators or references are invalidated.

but I'm wondering whether the for(auto ...) will continue through all the items that I appended along the way.

CodePudding user response:

For-range is just a syntactic sugar for a classic for loop operating on iterators. As long as your container implements begin and end (or you have free overloads), and don't invalidate the iterator in the process, this should technically be fine. Other thing is whether this is a good and maintainable idea.

Before C 17:

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

From C 17:

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