In C++, I can write a statement std::string& x = f();
. If f()
returns a std::string
(not a reference), it will extend the lifespan of the temporary variable until x
goes out of scope.
What if I wanted to write something like std::string& x = identity(f());
, where identity
should "pass through" the value. Is there a way to do so which can extend the lifespan of the temporary value returned by f()
just like it did in the simpler case?
I'm willing to overload identity
as needed to support the different kinds of references if needed, but the rules for lifespan extension were always tricky, so I'm not sure if it can be done.
In C++, I can write a statement std::string& x = f();. If f() returns a std::string (not a reference), it will extend the lifespan of the temporary variable until x goes out of scope.
No, the program would be ill-formed and the compiler should fail to compile it or at least provide some diagnostic.
If you had used const std::string&
or std::string&&
instead, then you would be correct.
What if I wanted to write something like std::string& x = identity(f());, where identity should "pass through" the value. Is there a way to do so which can extend the lifespan of the temporary value returned by f() just like it did in the simpler case?
No, it will never extend the lifetime of the temporary past the full-expression. It is impossible to extend lifetime through any function call.
The reason is that generally C++ is designed in such a way that a compiler is only required to consider the declaration of a function, not its body/definition, while compiling a call to it, even if an optimizing compiler with optimizations enabled will generally still do so if it sees a definition in the same translation unit or link time optimization is enabled. Calls to constexpr
functions in (potential) constant expressions and functions requiring return type deduction are somewhat exceptions.
So you can't rely on knowing how identity
will forward the reference. But the caller would need to know that if it was supposed to extend the lifetime of the temporary which was created in its context and for which it is responsible.