2015-02-09 48 views
6

下编译没有错误:返回布展仅式编译即使拷贝构造函数是不可用

#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(); 
} 

我认为的f()返回值被x复制初始化,但std::unique_ptr是MOVE-只有类型。这是不是因为复制构造函数不可用而不合格?标准中的相关条款是什么?有没有什么地方说,如果f()是一种只能移动的类型而不是返回语句变成移动结构而不是复制结构?

+1

不知道,如果它是一个重复的[C++返回值优化(HTTP: //stackoverflow.com/questions/19454068/c-return-value-optimization)。 – iammilind 2015-02-09 13:15:03

+1

@iammilind:不是。 – 2015-02-09 13:19:06

+1

http://stackoverflow.com/questions/4316727/returning-unique-ptr-from-functions – vsoftco 2015-02-09 13:22:09

回答

12

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

f()返回值确实是从表达x复制初始化,但复制初始化并不总是意味着禁止复制建设。如果表达式是一个右值,那么移动构造函数将被重载解析(假设存在移动构造函数)。

现在虽然这是事实,在return x;语句表达x是一个左值(这可能会导致您认为我只是写不适用),在情况下返回具有自动存储持续时间命名对象,编译器应首先尝试将id-表达式作为重载解析的右值。

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?

每C++标准([class.copy]/32,N4296草案)第12.8/32:

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

..因此移动构造函数是合格的,呈现_“f()的返回值被复制初始化为x“_ false。 ''' – 2015-02-09 13:14:00

+0

最好说你正在引用的_which_ C++标准,因为有几个标准。 – 2015-02-09 13:15:53

+0

@LightnessRacesinOrbit:它不会使该语句为假。 AFAIK复制初始化并不意味着复制构建。关于标准版本,将编辑,谢谢。 – 2015-02-09 13:17:35