rvalue的生命周期绑定到静态const引用

sbi*_*sbi 14 c++ reference temporary

考虑一下:

std::string foo();

void bar() {
         const std::string& r1 = foo();
  static const std::string& r2 = foo();
}
Run Code Online (Sandbox Code Playgroud)

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

r2然而,暂时的约束呢?它会一直存在到示波器的末端,还是在bar()重新进入时仍然存在?

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

Lig*_*ica 7

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

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

  • 绑定到构造函数的ctor-initializer(12.6.2)中的引用成员的临时绑定将持续存在,直到构造函数退出.
  • 函数调用(5.2.2)中的引用参数的临时绑定将持续到包含该调用的完整表达式完成为止.
  • 函数返回语句(6.6.3)中返回值临时绑定的生命周期未扩展; 临时在return语句中的full-expression结束时被销毁.
  • new-initializer(5.3.4)中对引用的临时绑定将持续到包含new-initializerfull-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
    
    Run Code Online (Sandbox Code Playgroud)

-end example] [注意:这可能会引入一个悬空引用,并鼓励实现在这种情况下发出警告. - 尾注]

(特别要注意,没有一个项目符合这种情况.)

因此,在这种情况下,它基本上直到程序结束.

当然,我们可以非常简单地测试这个:

#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";
}
Run Code Online (Sandbox Code Playgroud)

结果:

main()
ctor
bye
dtor

(现场演示)