Return compilation of type move-only, even if the copy constructor is not available

The following compilation without errors:

#include <memory> std::unique_ptr<int> f() { std::unique_ptr<int> x(new int(42)); return x; } int main() { std::unique_ptr<int> y = f(); } 

I thought the return value of f() was initialized with a copy of x , but std::unique_ptr is a std::unique_ptr -only type. How is it not so bad because the copy constructor is not available? What is the relevant provision in the standard? Is there somewhere, if it is indicated that f() is a move-only type, than does the return statement become a move construct instead of a copy construct?

+6
source share
1 answer

I thought the return value of f() was initialized with x , but std::unique_ptr is a std::unique_ptr -only type

The return value of f() indeed copied using the expression x , but initializing the copy does not always mean creating a copy. If the expression is an r-value, then the move constructor will be selected using the overload resolution (assuming there is a move constructor).

Now, although it is true that the expression x in the statement return x; is an lvalue (which may make you think that what I just wrote does not apply), in situations where a named object with automatic storage duration is returned, the compiler should first try to treat the id expression as an rvalue to resolve overloading.

What is the relevant article in the standard? Is there somewhere that says f() is a move-only type, than does the return become a move construct instead of a copy construct?

In paragraph 12.8 / 32 of the C ++ Standard ([class.copy] / 32, draft N4296):

When the criteria for performing the copy / move operation are met, but not for declaring an exception, but the object to be copied is denoted by lvalue or when the expression in the return expression is (possibly in brackets) an id expression that names the object with automatic storage time declared in the body or parameter-declaration-sentence of the innermost enclosing function or lambda expression, overload resolution to select the constructor for the copy is first executed as if the object was designated rval ue. [...]

+12
source

Source: https://habr.com/ru/post/982205/


All Articles