在编译一些奇怪的代码以获得更好的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
所以,正如你在这里看到的那样,临时对象被绑定为引用,即使它首先被转换为引用类型。我不确定为什么会这样。我自己试着回答这个问题,这是我的想法:
C()
创建一个临时prvalue 申请static_cast
5.2.9p4:
否则,如果声明
e
很好,则可以使用T
形式的static_cast
将表达式static_cast<T>(e)
显式转换为T t(e);
类型形成了一些发明的临时变量t
(8.5)。这种显式转换的效果与执行声明和初始化相同,然后使用临时变量作为转换的结果。
因此创建了临时引用,static_cast
表达式的结果为左值
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
答案 0 :(得分:-1)
尝试查看标准的第12.2 / 4和12.2 / 5条:
有两种情况,临时表现在不同点,而不是表达结束。第一个上下文是调用默认构造函数来初始化数组的元素。如果 构造函数有一个或多个默认参数,破坏默认情况下创建的每个临时值 在构造下一个数组元素之前,参数会被排序。
- 醇>
第二个上下文是引用绑定到临时的。引用所在的临时值 绑定或临时,即绑定引用的子对象的完整对象仍然存在 在参考文件的生命周期中除外:...
这应该回答你的问题 - 为什么延长寿命。