const引用临时引用

时间:2015-03-20 08:50:40

标签: c++ reference language-lawyer temporary-objects

#include <iostream>
using namespace std;

struct CL
{
    CL()
    {
        cout<<"CL()"<<endl;
    }
    CL(const CL&)
    {
        cout<<"CL(const CL&)"<<endl;
    }
    ~CL()
    {
        cout<<"~CL()"<<endl;
    }
};

CL cl;

CL fnc()
{
    return cl;
}

int main() {
    cout<<"start"<<endl;
    const CL& ref=static_cast<const CL&>(fnc());
    //...Is "ref" valid here??
    cout<<"end"<<endl;
    return 0;
}

fnc()返回的临时对象的生命周期是什么?这是&#34; ref&#34;或临时引用static_cast(fnc()),它在语句结束时被销毁?

gcc的输出(fnc()的生命周期是&#34; ref&#34;)的生命周期:

CL()  //global object "cl"
start
CL(const CL&)
end
~CL()
~CL() //global object "cl"

VS2013的输出(fnc()的寿命是临时参考的寿命):

CL()  //global object "cl"
start
CL(const CL&)
~CL()
end
~CL() //global object "cl"

标准是什么?

1 个答案:

答案 0 :(得分:5)

我相信Visual Studio在这里是正确的,这在defect report #1376中有所说明:

  

在像

这样的声明中
T&& r = static_cast<T&&>(T());
     

目前尚不清楚T临时的寿命应该是多少。   根据5.2.9 [expr.static.cast]第4段,static_cast是   相当于发明临时变量t的声明。该   临时的生命周期延长到t的生命周期,但事实并非如此   清楚那个生命应该是什么,也不是后来的t的约束   到r会影响原来临时的生命周期。 (也可以看看   问题1568。)

讨论包括这个结论:

  

引用绑定到static_cast的xvalue结果,因此不会扩展临时的生命周期,此示例会导致悬空引用。

defect report 1568更具体地涵盖了这个案例:

  

根据12.2 [class.temporary]第4-5段,

     
    

有两种情况下,临时演员在与完整表达结束时不同的地方被摧毁......

         

第二个上下文是引用绑定到临时的。引用绑定的临时值或临时值     引用绑定到的子对象的完整对象     坚持参考的一生......

  
     

目前尚不清楚这是否适用于以下示例:

struct S { };
const S& r = (const S&)S();

并且回复是:

  

此问题与问题1376重复。

所以在这种情况下:

const CL& ref=static_cast<const CL&>(fnc());

引用绑定到static_cast的结果而不是CL的结果,因此CL是一个悬空引用。

供参考C ++ 11标准草案5.2.9 [expr.static.cast] 草案中的相关文本:

  

否则,可以使用static_-形式的static_cast将表达式e显式转换为类型T.   (e)如果声明T t(e);对于一些发明的临时变量t(8.5),其形式良好。该   这种显式转换的效果与执行声明和初始化相同   使用临时变量作为转换的结果。如果和,表达式e用作glvalue   只有初始化将它用作glvalue。