Итак, я понимаю, что значение общего списка инициализаторов, определяемое в рамках охватывающего списка инициализаторов, имеет время жизни, которое заканчивается охватывающим списком инициализаторов
Вы говоря об объекте, созданном выражением prvalue {1, 2, 3}
, верно?
Пример в decl.init.list / 6 ,
Массив имеет такое же время жизни, как и любой другой временный объект ([ class.porary ]), за исключением того, что инициализация объекта initializer_list
из массива продлевает время жизни массива точно так же, как привязка ссылки к временному объекту. [ Пример:
// ...
std::initializer_list<int> i3 = { 1, 2, 3 };
// ...
из которых в стандарте (или черновике) указано
Для i3
объект initializer_list
переменная, поэтому массив сохраняется в течение всего времени существования переменной.
Это говорит о том, что объект должен быть материализован и его время жизни должно быть увеличено.
Однако вы не инициализация объекта initializer_list
из выражения, потому что ваша переменная уже инициализирована. Если бы мы переписали ваш код как вызов условного
module_options.operator=({1, 2, 3})
, то мы бы не ожидали, что временное время жизни будет продлено после окончания вызова функции.
Я подозревал, что Временный по-прежнему будет жить до конца полного выражения, поскольку я думал, что привязка ссылки к должна была продлить его время жизни, а не уменьшать его: но, по общему признанию, class.porary / 6 говорит "... сохраняется в течение всего времени существования ссылки ..." , а не "... сохраняется по крайней мере время жизни ..."
Однако это означает, что следующий вариант вашего исходного кода должен делать то, что вы хотите:
std::map<int, std::vector<int>> ex = []{
/* for reused lists */
std::initializer_list<int> module_options { 1, 2, 3 };
return (decltype(ex)) {
{1, module_options},
{2, module_options},
};
}();