【问题标题】:Can a const int ref in a constructor safely bind to a literal?构造函数中的 const int ref 可以安全地绑定到文字吗?
【发布时间】:2015-03-26 10:02:04
【问题描述】:

我知道标准对延长临时对象的生命周期有一个例外,基本上说在构造函数中绑定 const 引用不会延长生命周期,但这也适用于文字吗?例如:

class C {
    private:
        const int& ref;
    public:
        C(const int& in)
            : ref{in}
        { }
};

如果我有一个函数返回这种类型的对象

C f() {
    C c(2);
    return c;
}

如果我知道绑定到文字,c.ref 的值会在调用者中未定义吗?

【问题讨论】:

  • 答案可能取决于编译器是否为文字创建了一个全局静态值并指向该值,或者它是否创建了一个堆栈值来指向。可以去任何一种方式。
  • 为什么不按值传递 int 呢?这样会更有效率。
  • @cppguy 这是一个非常小的实际问题示例。
  • @cppguy 认为int 类型可以是模板参数,如果这个例子稍微改写的话。

标签: c++ reference language-lawyer temporary object-lifetime


【解决方案1】:

。构造函数完成执行后,您将无法使用该引用。
当非类类型的纯右值绑定到同一类型的const-reference 时,总是会引入一个临时值。因此,构造函数的参数引用将引用一个临时的,一旦引用超出范围就会被销毁。发生这种情况后,成员引用悬空,并且尝试访问该引用后面的存储值会导致 UB。 [dcl.init.ref]/5:

对类型“cv1T1”的引用由以下表达式初始化 输入“cv2T2”如下:

  • 如果引用是左值引用和初始化表达式
    • 是一个左值(但不是位域),并且 [..]
    • 有一个类类型(即T2 是一个类类型)[..]
  • 否则,引用应为对非易失性const 类型的左值引用(即,cv1 应为 const),或引用 应该是一个右值引用。

    • 如果初始化表达式

      • 是一个 xvalue(但不是位域)、类纯右值、数组纯右值或函数左值和 [..]
      • 有一个类类型 [..]
    • 否则:(5.2.2.1)

      • 如果T1 是类类型[..]
      • 如果 T1 是非类类型,则会从初始化表达式创建并复制初始化 (8.5) 类型的“cv1 T1”临时。 然后将引用绑定到临时文件。

毫无疑问,整数文字确实是纯右值。 [expr.prim.general]/1:

字符串字面量是左值;所有其他文字都是纯右值。

最后,如果不清楚,[class.temporary]/5:

引用绑定的临时对象或被绑定的临时对象 引用绑定到的子对象的完整对象 在引用的生命周期内持续存在,除了:

  • 临时绑定到构造函数的 ctor-initializer (12.6.2) 中的引用成员将持续存在,直到构造函数退出。

【讨论】:

  • 在标准中也有:在构造函数的 ctor-initializer (§12.6.2) 中临时绑定到引用成员会一直持续到构造函数退出
  • 不错!最近只是在看这个,这就是为什么我手头有参考(双关语)。
  • @MatiasFG 是的,但我实际上不知道去哪里找(我只是打算搜索)。谢谢!
【解决方案2】:

简答:评估c.ref 几乎肯定是非法的(调用未定义的行为)。

长答案: 绑定对整数文字的引用时,您真正要做的是:

整数字面量指的是所谓的“a value that is not associated with an object”。

要绑定对它的引用,需要创建一个具有相同值的对象。这样做的原因是引用(或指针)必须始终指向一个对象(而这只不过是一点内存)。因此,创建了一个 临时 对象来保存该值。

只要正在评估创建它们的表达式,就可以保证临时对象持续存在。由于您的对象存在的时间更长,因此保存您的值的临时对象将被提前销毁,并且可能无法再访问该引用。

请注意,如果您在创建 c 的表达式中访问 c.ref,实际上就可以了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-16
    • 2018-08-22
    相关资源
    最近更新 更多