Можно ли продлить время жизни объектов в списке инициализатора?
У меня сложилось впечатление, что 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
болтается