Можно ли продлить время жизни объектов в списке инициализатора? - PullRequest
0 голосов
/ 15 декабря 2018

У меня сложилось впечатление, что 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 Ответ

0 голосов
/ 15 декабря 2018

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

В вашем случае initializer_list относится к временному массиву const double[3], время жизни этого массива описывается следующим образом:

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

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

и

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

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

...