I don't have much experience with initializer_list s, but the standard seems to suggest that the initializer_list implementation looks like a pair of pointers to an array. The list in getInitializer has an automatic lifetime, as well as an array that supports it. You end up returning a pair of pointers to an array that no longer exists.
The relevant sections of the standard are 8.5.4 [decl.init.list] clauses 5 and 6:
5.- An object of type std::initializer_list<E> is created from the list of initializers, as if the implementation allocated an array of N elements of type E , where N is the number of elements in the list of initializers. Each element of this array is initialized with a copy with the corresponding element in the list of initializers, and the std::initializer_list<E> object is created to access this array. If the initialization of any element requires a narrowing of the transformation, the program is poorly formed.
6.- The lifetime of the array is the same as that of the initializer_list object.
So, for your specific case, the implementation will be roughly equivalent to this:
std::initializer_list<std::function<std::string()>> getInitializer() { std::function<std::string()> __a[1] = { []() -> std::string { return "If"; } }; return std::initializer_list<std::function<std::string()>>(__a, __a+1); }
source share