绑定到静态常量引用的右值的生命周期
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)
考虑一下:
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