Temporary在首先被强制转换为引用类型时仍然绑定到引用

Temporary is still binded to reference, when casted to reference type first

本文关键字:引用类型 绑定 引用 转换 Temporary      更新时间:2023-10-16

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

struct C {
    C() { cout << "Constructedt" << this << "n"; }
    C(const C& source) = delete;
    C(C&&) = delete;
    ~C() { cout << "Destructedt" << 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:

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

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

  3. 接下来会发生什么,为什么临时的寿命会延长?它是不是有点像临时绑定到临时引用,而临时引用本身又绑定到其他引用

p.S.也尝试过这个(添加一个地址获取和撤销运算符):

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

而gcc的输出仍然是:

Constructed 0x7fffa1c50157
Next line
Destructed  0x7fffa1c50157

在这种情况下,在"下一行"之前临时销毁:

Constructed 0x7fff3374ab60
Destructed  0x7fff3374ab60
Next line

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

  1. 在两种上下文中,临时性在与完整表达式结尾不同的位置被销毁。第一个上下文是当调用默认构造函数来初始化数组的元素时。如果构造函数有一个或多个默认参数,即销毁在默认值中创建的每个临时参数参数在构造下一个数组元素(如果有的话)之前进行排序。

  2. 第二个上下文是引用绑定到临时的。引用所指向的临时绑定的或作为引用绑定到的子对象的完整对象的临时对象仍然存在在引用的生命周期内,除了:。。。

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