临时仍然绑定到引用,当第一次转换为引用类型时

时间:2014-10-14 09:36:37

标签: c++

在编译一些奇怪的代码以获得更好的C ++标准理解时,我遇到了一个例子,我实际上并不确定发生了什么。考虑一个简单的类,它在构造或销毁时产生调试输出:

struct C {
    C() { cout << "Constructed\t" << this << "\n"; }
    C(const C& source) = delete;
    C(C&&) = delete;
    ~C() { cout << "Destructed\t" << this << "\n"; }
};

现在代码,我不理解的行为:

int main()
{
    const C& r = static_cast<const C&>(C());
    cout << "Next line" << endl;
}

输出是(用gcc和clang尝试过):

Constructed 0x7fff6d6ebe60  
Next line  
Destructed  0x7fff6d6ebe60

所以,正如你在这里看到的那样,临时对象被绑定为引用,即使它首先被转换为引用类型。我不确定为什么会这样。我自己试着回答这个问题,这是我的想法:

  1. C()创建一个临时prvalue
  2. 申请static_cast 5.2.9p4:

      

    否则,如果声明e很好,则可以使用T形式的static_cast将表达式static_cast<T>(e)显式转换为T t(e);类型形成了一些发明的临时变量t(8.5)。这种显式转换的效果与执行声明和初始化相同,然后使用临时变量作为转换的结果。

    因此创建了临时引用,static_cast表达式的结果为左值

  3. 接下来会发生什么以及为什么延长临时寿命?它是否类似于临时绑定到临时引用,它本身与其他引用相关联?
  4. P.S。也尝试了这个(添加一个地址获取和derefernce运算符):

    int main()
    {
        const C& r = *&static_cast<const C&>(C());
        cout << "Next line" << endl;
    }
    

    gcc输出仍然是:

    Constructed 0x7fffa1c50157
    Next line
    Destructed  0x7fffa1c50157
    

    虽然在这种情况下clang在“下一行”之前暂时销毁:

    Constructed 0x7fff3374ab60
    Destructed  0x7fff3374ab60
    Next line
    

1 个答案:

答案 0 :(得分:-1)

尝试查看标准的第12.2 / 4和12.2 / 5条:

  
      
  1. 有两种情况,临时表现在不同点,而不是表达结束。第一个上下文是调用默认构造函数来初始化数组的元素。如果   构造函数有一个或多个默认参数,破坏默认情况下创建的每个临时值   在构造下一个数组元素之前,参数会被排序。

  2.   
  3. 第二个上下文是引用绑定到临时的。引用所在的临时值   绑定或临时,即绑定引用的子对象的完整对象仍然存在   在参考文件的生命周期中除外:...

  4.   

这应该回答你的问题 - 为什么延长寿命。