Reputation: 650
Is there something wrong if I write something like this:
Try<std::unique_ptr<int> > some_function() {
std::unique_ptr<int> s(new int(2));
return s;
}
Is the copy constructor invoked? Should I use std::move?
Upvotes: 2
Views: 410
Reputation: 96810
In a return statement, overload resolution can be performed as if the id-expression in the return statement designates an rvalue:
When the criteria for elision of a copy/move operation are met, [..], or when the expression in a return statement is a (possibly parenthesized) id-expression that names an object with automatic storage duration declared in the body [..], overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue.
So your case does indeed qualify for NRVO since s
is declared in the body of the function, thus std::move()
is not required as overload-resolution can treat s
as an rvalue.
Note that std::move()
might still be needed if your compiler doesn't support the first phase of overload resolution treating s
as an rvalue when the type of the return expression doesn't have the same cv-unqualified type as the function's return type. This seems to be the case with the trunk version of clang but not gcc. More info in this thread.
Upvotes: 3
Reputation: 38218
std::unique_ptr
doesn't have a copy constructor. What you're doing there is the same as assigning with a unique_ptr: the pointer is moved. (though in some situations you have to explicitly move()
the pointer or else you'll get a compilation error; but if the compiler doesn't complain with an error, then it's quietly moving the pointer)
Upvotes: 3