Ответ 1
Из С++ 11 8.5.4 Инициализация списка [dcl.init.list]:
5 Объект типа
std::initializer_list<E>
создается из списка инициализаторов, как если бы реализация выделила массив элементовN
типаE
, гдеN
- количество элементов в списке инициализаторов. Каждый элемент этого массива инициализируется копией с соответствующим элементом списка инициализаторов, а объектstd::initializer_list<E>
создается для обращения к этому массиву. Если для инициализации любого из элементов требуется сужение преобразования, программа плохо сформирована.6 Время жизни массива такое же, как у объекта
initializer_list
.
Оператор return
вашей лямбды инициализирует временный std::initializer_list<int>
и возвращает его копию. Это все хорошо, за исключением того, что время жизни массива, к которому он относится, заканчивается в конце полного выражения. Доступ к мертвому массиву через initializer_list
вне лямбда приводит к поведению undefined.
An initializer_list
не является контейнером, это ссылка на временный контейнер. Если вы попытаетесь использовать его как контейнер, у вас будет плохое время.
В С++ 14 (цитируя N4140) пункт 6 разъяснен следующим образом:
6 Массив имеет такое же время жизни, что и любой другой временный объект (12.2), за исключением того, что инициализация объекта
initializer_list
из массива продлевает время жизни массива точно так же, как привязка ссылки к временному.
по разрешению CWG issue 1290. Это разъяснение делает невозможным использование initializer_list
как, например, переменной-члена, которая была намерением С++ 11. Однако даже в С++ 14 ваша программа имеет поведение undefined.