【问题标题】:C++ temporary variable lifetimeC++ 临时变量生命周期
【发布时间】:2012-05-19 09:20:09
【问题描述】:

这段代码有效吗?

int foo()
{
    std::vector<std::string>& v = std::vector<std::string>(5, "X");

    // Do something silly...

    return 42;
}

出于某种原因,我认为临时std::vector 对象(从赋值符号开始) 应该在构造后立即销毁(从而使引用无效) .

但是,调试证明我错了,好吧,我意识到我不太明白为什么在函数返回时会破坏临时变量。


我想我对一些基本的东西有很大的误解,所以请赐教:)

【问题讨论】:

  • 当你说“调试证明我错了”时,你到底是什么意思?

标签: c++ visual-studio variables lifetime construction


【解决方案1】:

您显示的代码是非法的——临时代码只能绑定到右值引用或 const 左值引用。

VC++ 恰好允许它作为扩展名(并给出a level 4 warning 这么说)。

【讨论】:

  • gcc 对此抱怨得很好:error: invalid initialization of non-const reference of type 'std::vector&lt;std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;, std::allocator&lt;std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt; &gt;&amp;' from a temporary of type 'std::vector&lt;std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;, std::allocator&lt;std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt; &gt;
  • 谢谢,不知道那个扩展程序(而且,应该试过gcc)。
  • @Yippie-Kai-Yay :那么您应该在启用 4 级警告的情况下进行构建。 ;-]
  • 请注意,如果它是一个 const 引用,则它是合法的。对于 const 引用,临时对象的生命周期延长到 const 引用的生命周期,恰好是函数的结束。
  • @Yippie-Kai-Yay :在这种情况下,是的,正是——VC++ 自己的框架(MFC/ATL)滥用了这个扩展。请注意,C++ 标准特别允许 语言扩展,这些扩展使否则格式错误的代码能够编译,只要编译器发出诊断(在这种情况下为警告)。您只是没有看到诊断,因为默认警告级别是 3。:-]
【解决方案2】:

临时的正常生命周期是直到完整的结束 创建它的表达式;它不一定被破坏 立即使用。如果临时用于初始化引用, 它的生命周期被延长以匹配参考的生命周期(与 在 a 的初始化程序列表中创建的临时变量的显着例外 构造函数)。

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

【讨论】:

    【解决方案3】:

    您有一个对已释放对象的引用。它是靠“运气”工作的(参见 C++ 编程语言,第 10.4.10 节临时对象)。你不能保证它可以在每个编译器中工作。

    只有绑定到const 引用时,才能确定临时的生命周期会延长。

    【讨论】:

    • 在这种情况下并不是纯粹的运气,它是 OP 正在使用的编译器提供的语言扩展。
    • @ildjarn 我只是在开玩笑地引用 Stroustrup。关键是它是不可移植的/非法的/不可靠的或者你想怎么称呼它。
    • 它不是可移植的,同意,但也不违法; C++ 标准(第 1.4/8 节)特别允许语言扩展,只要扩展不影响格式良好代码的行为,并且编译器会发出诊断(警告计数)。
    • 请注意,当标准讨论临时对象的生命周期时,它谈到了延长绑定到引用的临时对象的生命周期。它没有说任何关于 const 或不存在的内容。所以从逻辑上讲,如果编译器接受使用临时的非常量引用的初始化,它也会延长临时的生命周期。
    猜你喜欢
    • 2012-05-19
    • 2021-05-17
    • 1970-01-01
    • 2010-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多