Reputation: 8239
Even if the subject was discussed many times around here, I can't find a conclusive explanation regarding my particular case. Will const
extend the lifetime of the RefTest
temporary? Is the below example legal?
#include <iostream>
class RefTest
{
public:
RefTest(const std::string &input) : str(input) {}
~RefTest () {std::cout << "RefTest" << std::endl;}
private:
std::string str;
};
class Child
{
public:
Child (const RefTest &ref) : ref_m(ref) {}
~Child () {std::cout << "Test" << std::endl;}
private:
const RefTest &ref_m;
};
class Test
{
public:
Test () : child(RefTest("child")) {}//Will the temporary get destroyed here?
~Test () {std::cout << "Test" << std::endl;}
private:
const Child child;
};
int main ()
{
Test test;
}
Upvotes: 12
Views: 22460
Reputation: 17021
The C++ standard states:
The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object to a subobject of which the temporary is bound persists for the lifetime of the reference except as specified below. 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.
NOTE: And by the way, this is duplicate (1, 2), you should search better, next time... :)
Upvotes: 10
Reputation: 171263
The reference does not extend the lifetime. The code is legal, but only because you never access ref_m
after the constructor finishes.
The temporary is bound to the constructor parameter, ref
. Binding another reference to it later, ref_m
, doesn't extend the lifetime. If it did, you'd have an object on the stack which has to persist as long as the reference member it's bound to, which could be allocated on the heap, so the compiler would be unable to unwind the stack when the constructor returns.
It would be nice to get a warning, but compilers aren't perfect and some things are difficult to warn about. The temporary is created in a different context from where it's bound to a reference, so the compiler can only tell there's a problem with inlinging turned on, or some clever static analysis.
Upvotes: 13