将 const 引用成员设置为临时变量是否安全?

Apl*_*Ddr 6 c++ reference constants temporary lifetime

我试过多次这样编码:

struct Foo
{
    double const& f;
    Foo(double const& fx) : f(fx)
    {
        printf("%f %f\n", fx, this->f); // 125 125
    }

    double GetF() const
    {
        return f;
    }
};
int main()
{
    Foo p(123.0 + 2.0);
    printf("%f\n", p.GetF()); // 0
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但它根本不会崩溃。我还使用valgrind来测试程序,但没有出现错误或警告。所以,我假设编译器自动生成了一个代码,将引用指向另一个隐藏变量。但我真的不确定。

son*_*yao 9

不,这不安全。更准确地说,这是UB,意味着一切皆有可能。

当您传递123.0 + 2.0给 的构造函数时Foodouble将构造一个临时对象并将其绑定到参数fx。在完整表达式(即Foo p(123.0 + 2.0);)之后临时将被销毁,然后引用成员f将变为悬空。

请注意,临时的生命周期不会延长到引用成员的生命周期f

通常,不能通过“传递”来进一步延长临时文件的生命周期:从临时文件绑定的引用初始化的第二个引用不会影响其生命周期。

从标准,[class.base.init]/8

绑定到内存初始值设定项中的引用成员的临时表达式格式错误。[?例子:

struct A {
  A() : v(42) { }   // error
  const int& v;
};
Run Code Online (Sandbox Code Playgroud)

—?最后的例子?]