Можно ли продлить время жизни объектов в списке инициализатора?

У меня сложилось впечатление, что std::initializer_list может вести себя как строковые литералы в C++, и даже дальше они могут продлить время жизни ссылок на const. Это правильная оценка?

Может объекты в initializer_list ссылаться позже (не копируя их), в локальной области видимости? в глобальном масштабе?

Например, эти тесты проходят в GCC и Clang. Это просто случайно?

#include<cassert>
#include<initializer_list> 
struct A{
    double const* p;
    A(std::initializer_list<double> il){ p = &*(il.begin() + 1); };
};
double f(){return 5.;}
int main(){
   A a1{1.,2.,3.};
   assert( *a1.p == 2. );
   A a2{1., f(), f()};
   assert( *a2.p == 5. );
}

1 ответ

Это неопределенное поведение.

В твоем случае initializer_list ссылается на временный массив const double[3]время жизни этого массива описано ниже:

ref Гарантируется, что базовый массив не существует после истечения времени жизни исходного объекта списка инициализаторов. [до с ++14]

Время жизни базового массива такое же, как и у любого другого временного объекта [начиная с C++14]

а также

ref Все временные объекты уничтожаются как последний шаг в оценке полного выражения

так в вашем случае, когда конструктор A вызывается, создается временный массив с 3 double, затем вы берете адрес элементов временного массива, и когда конструктор завершает работу, временный массив уничтожается (в этом случае полное выражение является вызовом ctor), в результате p болтается

Другие вопросы по тегам