Returning move-only type compiles even though copy-constructor is unavailable

后端 未结 1 1115
我在风中等你
我在风中等你 2021-01-12 03:31

The following compiles without error:

#include 

std::unique_ptr f() {
    std::unique_ptr x(new int(42));
    return x;
         


        
相关标签:
1条回答
  • 2021-01-12 03:46

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

    The return value of f() is indeed copy-initialized from the expression x, but copy-initialization does not always imply copy-construction. If the expression is an rvalue, then the move constructor will be picked by overload resolution (assuming a move constructor is present).

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

    What is the relevant clause in the standard? Is there somewhere that says if f() is a move-only type than a return statement becomes a move construction instead of a copy construction?

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

    When the criteria for elision of a copy/move operation are met, but not for an exception-declaration, and the object to be copied is designated by an lvalue, 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 or parameter-declaration-clause of the innermost enclosing function or lambda-expression, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue. [...]

    0 讨论(0)
提交回复
热议问题