Я просто додам трохи деталей. Основний масив std::initializer_list
поведінки схожий на тимчасовий. Розглянемо наступний клас:
struct X
{
X(int i) { std::cerr << "ctor\n"; }
~X() { std::cerr << "dtor\n"; }
};
та його використання у наступному коді:
std::pair<const X&, int> p(1, 2);
std::cerr << "barrier\n";
Це роздруковується
ctor
dtor
barrier
оскільки в першому рядку створюється тимчасовий екземпляр типу X
(шляхом перетворення конструктора з 1
) і також знищується. Посилання, збережене в p
, то висить.
Що стосується std::initializer_list
, якщо ви використовуєте його таким чином:
{
std::initializer_list<X> l { 1, 2 };
std::cerr << "barrier\n";
}
то нижній (тимчасовий) масив існує до тих пір, поки l
виходить. Тому вихід:
ctor
ctor
barrier
dtor
dtor
Однак якщо перейти на
std::pair<std::initializer_list<X>, int> l { {1}, 2 };
std::cerr << "barrier\n";
Вихід знову
ctor
dtor
barrier
оскільки базовий (тимчасовий) масив існує лише у першому рядку. Перенаправлення покажчика на елементи l
тоді призводить до невизначеної поведінки.
Демо демо тут .
std::pair
.