test(2).test_method()
returns the link attached to test2
, and then the object to which it refers is destroyed at the end of the full expression, since it is a temporary object. This should not be a surprise.
The real surprise is that test1
remains a valid link because it is directly linked to a temporary one, and linking the temporary to the link extends the lifetime from the temporary to the reference variable.
You only need to note that in the case of test(2)
temporary object is not attached to anything. He simply used to call some member function, and then his work was done. It does not serve as a babysit, or, in other words, extending life is not transitive with all possible future references.
Here is a simple thought experiment why it would be impossible to have an โarbitrary extension of lifeโ:
extern T & get_ref(T &); { T const & x = get_ref(T());
We do not know whether x
remains outside the first line. get_ref
can do anything. If it is implemented as T & get_ref(T & x) { return x; }
T & get_ref(T & x) { return x; }
, we can hope for magic, but it could also be like this:
namespace { T global; } T & get_ref(T & unused) { return global; }
It is not possible to decide within the original translation unit whether something needs to be extended or not. Thus, the standard at present is that it is a completely trivial local decision that was made only when considering the expression of the reference declaration, what should be the lifetime of a temporary object.
source share