I am trying to use std::initializer_list
in order to define and output recursive data-structures. In the example below I am dealing with a list where each element can either be an integer or another instance of this same type of list. I do this with an intermediate variant type which can either be an initializer list or an integer.
What is unclear to me is whether the lifetime of the std::initializer_list
will be long enough to support this use-case or if I will be experiencing the possibility of inconsistent memory access. The code runs fine, but I worry that this is not guaranteed. My hope is that the std::initializer_list
and any intermediate, temporary std::initializer_list
objects used to create the top-most list are only cleaned up after the top-level expression is complete.
struct wrapped {
bool has_list;
int n = 0;
std::initializer_list<wrapped> lst;
wrapped(int n_) : has_list(false), n(n_) {}
wrapped(std::initializer_list<wrapped> lst_) : has_list(true), lst(lst_) {}
void output() const {
if (!has_list) {
std::cout << n << ' ';
} else {
std::cout << "[ ";
for (auto&& x : lst) x.output();
std::cout << "] ";
}
}
};
void call_it(wrapped w) {
w.output();
std::cout << std::endl;
}
void call_it() {
call_it({1}); // [ 1 ]
call_it({1,2, {3,4}, 5}); // [ 1 2 [ 3 4 ] 5 ]
call_it({1,{{{{2}}}}}); // [ 1 [ [ [ [ 2 ] ] ] ] ]
}
Is this safe, or undefined behavior?