绑定到静态常量引用的右值的生命周期

Lifetime of rvalue bound to static const reference

考虑一下:

std::string foo();

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

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

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

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

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

[C++14: 12.2/5]: 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 except:

  • A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits.
  • A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full-expression containing the call.
  • The lifetime of a temporary bound to the returned value in a function return statement (6.6.3) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.
  • A temporary bound to a reference in a new-initializer (5.3.4) persists until the completion of the full-expression containing the new-initializer. [ Example:

    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
    

—end example ] [ Note: This may introduce a dangling reference, and implementations are encouraged to issue a warning in such a case. —end note ]

(特别注意 none 个要点与此场景匹配。)

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

当然,我们可以非常简单地进行测试:

#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()
ctor
bye
dtor

(live demo)