2015-02-09 52 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