【问题标题】:Lifetime of rvalue bound to static const reference右值的生命周期绑定到静态常量引用
【发布时间】:2015-10-02 23:45:00
【问题描述】:

考虑一下:

std::string foo();

void bar() {
         const std::string& r1 = foo();
  static const std::string& r2 = foo();
}

我知道第一次调用foo() 产生的字符串的生命周期将延长到r1 的生命周期。

但是,临时绑定到r2 呢?它会一直存在到范围结束,还是在重新输入bar() 时仍然存在?

注意:我对特定编译器是否这样做不感兴趣。 (我对我们使用的那个很感兴趣,我可以用它轻松测试。)我想知道标准对此有何规定。

【问题讨论】:

  • 独立于答案,这似乎是一种糟糕的编码风格,所以对于良好的编码风格,这个问题永远不会出现。
  • @SergeRogatch 你应该说用什么来代替。
  • @Melebius:只有在明确了实际目标时才能这样做。
  • 这对于自己测试来说完全是微不足道的......

标签: c++ reference temporary


【解决方案1】:

临时延长到引用的生命周期

[C++14: 12.2/5]: 引用绑定到的临时对象或作为引用绑定到的子对象的完整对象的临时对象在引用的生命周期内持续存在,除了:

  • 临时绑定到构造函数的 ctor-initializer (12.6.2) 中的引用成员会一直存在,直到构造函数退出。
  • 在函数调用 (5.2.2) 中与引用参数的临时绑定一直存在,直到包含调用的 full-expression 完成。
  • 临时绑定到函数返回语句 (6.6.3) 中的返回值的生命周期未延长;临时在 return 语句中的 full-expression 末尾被销毁。
  • 临时绑定到 new-initializer (5.3.4) 中的引用会一直持续到包含 new-initializer 的 full-expression 完成[示例:

    struct S { int mi; const std::pair<int,int>& mp; };
    S a { 1, {2,3} };
    S* p = new S{ 1, {2,3} }; // Creates dangling reference
    

—结束示例] [注意:这可能会引入悬空引用,鼓励实现在这种情况下发出警告。 ——尾注]

(特别要注意,没有一个项目符号与这种情况相符。)

所以,在这种情况下,基本上是直到程序结束。

当然,我们可以简单地测试一下:

#include <iostream>

struct Tracked
{
    Tracked() { std::cout << "ctor\n"; };
    Tracked(const Tracked&) { std::cout << "copy\n"; };
    ~Tracked() { std::cout << "dtor\n"; };
};

void foo()
{
    static const Tracked& ref = Tracked();
}

int main()
{
    std::cout << "main()\n";
    foo();
    std::cout << "bye\n";
}

结果:

main()
演员
再见
老师

(live demo)

【讨论】:

    猜你喜欢
    • 2015-11-18
    • 1970-01-01
    • 2015-04-22
    • 2011-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-27
    相关资源
    最近更新 更多