C++ C++;临时变量生存期

C++ C++;临时变量生存期,c++,visual-studio,variables,lifetime,construction,C++,Visual Studio,Variables,Lifetime,Construction,这个代码有效吗 intfoo() { 标准向量&v=标准向量(5,“X”); //做些傻事。。。 返回42; } 出于某种原因,我认为临时std::vector对象(位于赋值符号的右侧)应该在其构造之后立即销毁(从而使引用无效) 然而,调试证明我错了,我意识到我不太明白为什么当函数返回时临时变量会被破坏。 我想我对一些基本的东西有一个强烈的误解,所以请告诉我:)你展示的代码是非法的——临时变量只能绑定到右值引用或常量左值引用 VC++碰巧允许它作为扩展(并给出了这样的说法)。您有一个对解除分

这个代码有效吗

intfoo()
{
标准向量&v=标准向量(5,“X”);
//做些傻事。。。
返回42;
}
出于某种原因,我认为临时
std::vector
对象(位于赋值符号的右侧)应该在其构造之后立即销毁(从而使引用无效)

然而,调试证明我错了,我意识到我不太明白为什么当函数返回时临时变量会被破坏。



我想我对一些基本的东西有一个强烈的误解,所以请告诉我:)

你展示的代码是非法的——临时变量只能绑定到右值引用或常量左值引用


VC++碰巧允许它作为扩展(并给出了这样的说法)。

您有一个对解除分配对象的引用。它的工作原理是“纯粹的运气”(参见<强> C++编程语言<强>节,104.10临时对象)。您不能保证它在每个编译器中都能工作


只有当临时文件绑定到
常量
引用时,您才能确定临时文件的生存期是否延长。

临时文件的正常生存期是到完整引用结束时 在其中创建的表达式;它不一定被破坏 使用后立即使用。如果临时变量用于初始化引用, 它的生存期被延长以匹配引用的生存期(使用 在的初始值设定项列表中创建的临时 构造函数)

当然,你的代码是非法的;如果引用是非常量,则 只能用某种左值初始化。但如果是的话 合法(并且至少有一个编译器接受),生存期应该是
扩展以匹配引用的引用。

当您说“调试证明我错了”时,您的确切意思是什么?gcc对此抱怨得很好:
错误:从“std::vector”类型的临时变量初始化“std::vector&”类型的非常量引用无效谢谢,我不知道该扩展(而且,好吧,我们应该尝试一下
gcc
).@Yippie Kai Yay:那么您应该在启用4级警告的情况下进行构建。.-]请注意,如果它是常量引用,则它是合法的。对于常量引用,临时对象的生存时间将延长到常量引用的生存时间,这恰好是函数的结束。@Yippie Kai Yay:在这种情况下,是的,确切地说是–VC++自己的框架(MFC/ATL)滥用这个扩展。注意,C++标准特别允许语言扩展,否则编译器会编译错误的代码,只要编译器发出一个诊断(在这种情况下警告)。。您只是没有看到诊断,因为默认警告级别为3。:-]在这种情况下,这不是纯粹的运气,它是OP使用的编译器提供的语言扩展。@ildjarn我只是开玩笑地引用Stroustrup。重点是它不可移植/非法/不可靠,或者您想称之为的任何东西。它不可移植,agreED,但它也不是非法的;C++标准(第1.4或8)特别允许语言扩展,只要扩展不影响格式良好的代码的行为,编译器发出诊断(警告计数)。。请注意,当标准讨论临时引用的生存期时,它提到了延长绑定到引用的临时引用的生存期。它没有提到常量或不存在。因此,从逻辑上讲,如果编译器接受带有临时引用的非常量引用的初始化,它也会延长临时引用的生存期。
int foo()
{
    std::vector<std::string>& v = std::vector<std::string>(5, "X");

    // Do something silly...

    return 42;
}