In C , std::unique_ptr enforces move semantics to prevent multiple ownership of objects. However, it's possible to return a unique_ptr from a function without invoking std::move. This behavior can be attributed to a language feature called copy elision.
According to the C language specification (12.8 §34 and §35), an implementation is permitted to elide (omit) copy/move operations when certain criteria are met. Specifically, copy elision is allowed in a return statement for a class return type, provided that the expression is the name of a non-volatile automatic object with the same cv-unqualified type as the function return type.
In the example code you provided:
unique_ptr<int> foo() { unique_ptr<int> p(new int(10)); return p; // Line 1 }
p is a non-volatile automatic object that has the same type as the function return type, unique_ptr
When the compiler encounters line 1, it first performs overload resolution to select the constructor for the copy operation, as if p were designated by an rvalue. However, since the criteria for elision are met, the copy construction is elided and the returned value becomes a moved-out unique_ptr.
It's important to note that returning by value should be the default choice in this scenario. In the presence of copy elision, a named value in the return statement is treated as an rvalue. This means that even without explicitly using std::move, the returned unique_ptr can be moved from the function's temporary object.
Returning by reference or using std::make_unique are both viable alternatives to avoid copy elision and ensure explicit ownership transfer.
The above is the detailed content of Can I Return a `std::unique_ptr` Without `std::move` in C ?. For more information, please follow other related articles on the PHP Chinese website!