It seems like you're expecting the const
reference to extend the lifetime of the temporary. There are certain situations where this doesn't occur. One of those situations is when returning a temporary:
The second context [in which temporaries are destroyed at a different point than the end of the full-expression] 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 of a subobject to which the reference is bound persists for the lifetime of the reference except:
[...]
- 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.
Since calling a member function of the object returned by foo()
will necessitate an lvalue-to-rvalue conversion and the object is invalid (not derived from type base
), you get undefined behaviour:
If the object to which the glvalue refers is not an object of type T
and is not an object of a type derived from T
, or if the object is uninitialized, a program that necessitates this conversion has undefined behavior.