使const引用成员成为临时变量是否安全? [英] Is it safe to make a const reference member to a temporary variable?

查看:52
本文介绍了使const引用成员成为临时变量是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经尝试过几次这样的代码:

I've tried to code like this several times:

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;
}

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

But it doesn't crash at all. I've also used valgrind to test the program but no error or warning occured. So, I assume that the compiler automatically generated a code directing the reference to another hidden variable. But I'm really not sure.

推荐答案

不,这不安全.更确切地说,这是 UB ,表示一切皆有可能.

No, this is not safe. More precisely this is UB, means anything is possible.

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

When you pass 123.0 + 2.0 to the constructor of Foo, a temporary double will be constructed and bound to the parameter fx. The temporary will be destroyed after the full expression (i.e. Foo p(123.0 + 2.0);), then the reference member f will become dangled.

请注意,临时对象的寿命不会扩展为引用成员 f 的生​​存期.

Note that the temporary's lifetime won't be extended to the lifetime of the reference member f.

通常,不能通过将其传递"来进一步延长临时项的生存期:从临时项所绑定到的引用初始化的第二个引用不会影响其生存期.

In general, the lifetime of a temporary cannot be further extended by "passing it on": a second reference, initialized from the reference to which the temporary was bound, does not affect its lifetime.

根据标准, [class.base.init]/8

绑定到引用成员中的临时表达式mem初始化程序格式错误.[示例:

A temporary expression bound to a reference member in a mem-initializer is ill-formed. [ Example:

struct A {
  A() : v(42) { }   // error
  const int& v;
};

-示例]

这篇关于使const引用成员成为临时变量是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆