初始化列表中对象的生命周期可以延长吗?

alf*_*lfC 4 c++ lifetime initializer-list const-reference c++11

我的印象是,它的std::initializer_list行为可能类似于 C++ 中的文字字符串,甚至进一步,它们可能会延长 const 引用的生命周期。这是正确的评估吗?

initializer_list稍后可以在本地范围内以某种方式引用an 中的对象(无需复制它们)吗?在全球范围内?

例如,这个测试在 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. );
}
Run Code Online (Sandbox Code Playgroud)

raf*_*x07 7

这是未定义的行为。

在您的情况下,initializer_list指的是临时数组const double[3],该数组的生命周期描述如下:

ref 在原始初始化列表对象的生命周期结束后,不保证底层数组存在。[直到 c++14]

底层数组的生命周期与任何其他临时对象相同 [自 c++14 起]

ref所有临时对象都会在评估完整表达式的最后一步被销毁

因此,在您的情况下A,当调用 的构造函数时,将创建具有 3 个双精度数的临时数组,然后您将获取临时数组元素的地址,并且当构造函数结束时,临时数组将被销毁(在这种情况下,完整的表达式是 ctor 的调用),所以结果p是悬空指针。