std::unique_ptr<int> ptr() {
std::unique_ptr<int> p(new int(3));
return p; // Why doesn't this require explicit move using std::move?
} // Why didn't the data pointed to by 'p' is not destroyed here though p is not moved?
int main() {
std::unique_ptr<int> a = ptr(); // Why doesn't this require std::move?
std::cout << *a; // Prints 3.
}
In the above code, the function ptr()
returns a copy of p
. When p
goes out of scope, the data '3' should get deleted. But how does the code work without any access violation?
This is set out in the C++11 standard, § 12.8/32:
When the criteria for elision of a copy operation are met or would be met save for the fact that the source object is a function parameter, 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....
(emphasis mine). In plain english, it means that the lvalue p
can be treated as an rvalue
when it comes to overload resolution, because it is a candidate for copy elision. This in turn means the move constructor is picked up on overload resolution (in actual fact, the move copy is probably elided anyway.)