关于右值引用(rvalue reference)生命周期的技术咨询
Great question—this is one of those subtle C++ rules that confuses even experienced developers at first. Let’s break down your example and the underlying rules step by step.
What Happens with int&& value = 5;?
You’re right that 5 is a temporary rvalue object, which normally would be destroyed as soon as the expression it’s part of finishes executing. But when you bind a temporary object directly to an rvalue reference (or even a const lvalue reference), the C++ standard explicitly extends the temporary’s lifetime to match the lifetime of the reference variable.
In your example, the temporary int holding the value 5 won’t be destroyed until the variable value goes out of scope (e.g., at the end of the function block where it’s declared). You can even modify the value through the reference, since int&& is a mutable rvalue reference:
int main() { int&& value = 5; value = 42; // Totally valid—we're modifying the temporary object std::cout << value; // Outputs 42 } // `value` goes out of scope here, so the temporary is finally destroyed
Key Exceptions to Lifecycle Extension
It’s important to note that this lifecycle extension only applies to direct binding of the temporary to the reference. There are cases where extension doesn’t happen:
- When the reference is returned from a function: If a function returns an rvalue reference to a temporary (like
int&& func() { return 5; }), the temporary is destroyed when the function exits. The returned reference becomes a dangling reference, and using it is undefined behavior. - When the reference is a member of a class: If you bind a temporary to a reference member in a constructor’s initializer list, the temporary’s lifetime isn’t extended to the lifetime of the class object.
Practical Use Cases
Extending a temporary’s lifetime with an rvalue reference isn’t just a curiosity—it’s useful in several scenarios:
- Avoiding unnecessary copies: Instead of copying a temporary object into a named variable, you can bind it to an rvalue reference and use it directly.
- Enabling move semantics: Rvalue references are the foundation of move operations, where we transfer resources from temporary objects (like temporary
std::stringorstd::vectorinstances) to named objects without copying. - Capturing temporaries in complex expressions: If you need to reuse a temporary object across multiple lines of code, binding it to an rvalue reference lets you do so safely.
内容的提问来源于stack exchange,提问作者user2957984

