std::unique_ptr
Consider the following code snippet:
unique_ptr<int> foo() { unique_ptr<int> p(new int(10)); return p; // Line 1 } int main() { unique_ptr<int> p = foo(); cout << *p << endl; }
Line 1 returns a unique_ptr without std::move(). Surprisingly, the code compiles and operates as intended, so how is this possible without invoking the copy constructor?
The key to understanding this behavior lies in the C language specification. Specifically, section 12.8 §34 and §35 describe copy elision:
When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object [...].
In this case, copy elision is permitted because:
When the criteria for elision of a copy operation are met and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue.
This implies that although the return value is a named object (an lvalue), overload resolution still considers it as an rvalue. Thus, the move constructor is not invoked, and the returned unique_ptr is successfully constructed.
The ability to return a unique_ptr without std::move() is a subtle feature of the C language specification. It is not necessary to explicitly use std::move() when returning a unique_ptr from a function, as long as the conditions for copy elision are met. This can help improve code clarity and reduce unnecessary move operations.
The above is the detailed content of Why Does Returning a `std::unique_ptr` Not Require `std::move()`?. For more information, please follow other related articles on the PHP Chinese website!