The temporary is extended to the lifetime of the reference.
[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 ]
(In particular, note that none of the bullet points match this scenario.)
So, in this case, it's essentially until the program ends.
We can, of course, test this pretty trivially:
#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";
}
Result:
main()
ctor
bye
dtor