const引用到临时引用 [英] const reference to temporary reference

查看:141
本文介绍了const引用到临时引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#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()返回的临时对象的生存期是多少?是在引用结束时销毁的"ref"生存期还是临时引用static_cast(fnc())?

What's lifetime of temporary object returned by fnc()? Is it lifetime of "ref" or of temporary reference static_cast(fnc()), which destroyed at end of statement?

gcc的输出(fnc()的生存期为"ref"的生存期):

Output of gcc (lifetime of fnc() is lifetime of "ref"):

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

VS2013的输出(fnc()的生命周期是临时引用的生命周期):

Output of VS2013 (lifetime of fnc() is lifetime of temporary reference):

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

标准正确的是什么?

推荐答案

我相信Visual Studio在这里是正确的,这在

I believe Visual Studio is correct here, this is covered in defect report #1376 which says:

在类似

T&& r = static_cast<T&&>(T());

尚不清楚T临时对象的生存期应该是多少. 根据5.2.9 [expr.static.cast]第4段,static_cast为 等效于发明临时变量t的声明.这 临时的生存期延长到t的生存期,但不是 清楚该生存期应该是什么,也不知道随后的t绑定 r将影响原始临时文件的生命周期. (也可以看看 问题1568.)

it is not clear what the lifetime of the T temporary should be. According to 5.2.9 [expr.static.cast] paragraph 4, the static_cast is equivalent to a declaration of an invented temporary variable t. The lifetime of the temporary is extended to that of t, but it is not clear what that lifetime should be, nor if the subsequent binding of t to r would affect the lifetime of the original temporary. (See also issue 1568.)

并且讨论包括以下结论:

and the discussion includes this conclusion:

该引用绑定到static_cast的xvalue结果,因此不会延长临时项的生存期,此示例将导致悬空引用.

The reference is bound to the xvalue result of the static_cast, so the lifetime of the temporary is not extended and this example results in a dangling reference.

缺陷报告1568 涵盖了此内容情况更具体:

and defect report 1568 covers this case more specifically:

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

According to 12.2 [class.temporary] paragraphs 4-5,

在两种情况下,临时变量会在与完整表达式结束时不同的位置被破坏...

There are two contexts in which temporaries are destroyed at a different point than the end of the full-expression...

第二个上下文是将引用绑定到临时项时.引用绑定到的临时对象或引用的临时对象 引用绑定到的子对象的完整对象 在参考的有效期内持续存在...

The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference...

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

It is not clear whether this applies to an example like the following:

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

,回复为:

此问题与1376问题重复.

This issue is a duplicate of issue 1376.

在这种情况下:

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

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

the reference is bound to the result of the static_cast and not to CL and therefore CL is a dangling reference.

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

For reference the relevant text from the draft C++11 standard section 5.2.9 [expr.static.cast]:

否则,可以使用static_-形式的static_cast将表达式e显式转换为T类型. 如果声明T t(e),则强制转换(e);对于某些发明的临时变量t(8.5),其格式正确.这 这种显式转换的效果与执行声明和初始化然后执行 使用临时变量作为转换的结果.如果和,则将表达式e用作glvalue. 仅当初始化将其用作glvalue时.

Otherwise, an expression e can be explicitly converted to a type T using a static_cast of the form static_- cast(e) if the declaration T t(e); is well-formed, for some invented temporary variable t (8.5). The effect of such an explicit conversion is the same as performing the declaration and initialization and then using the temporary variable as the result of the conversion. The expression e is used as a glvalue if and only if the initialization uses it as a glvalue.

这篇关于const引用到临时引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆