2016-03-06 306 views
2

此代碼編譯成功。錯誤:這裏聲明unique_ptr(const unique_ptr&)= delete;

#include<iostream> 
#include<memory> 
using namespace std; 
class A{ 
     public: 
     unique_ptr<A> myval; 
     A(){ cout<<"Constrcutor of A is called"<<endl; } 
     ~A(){cout<<"Destructor of A is called"<<endl;} 
     unique_ptr<A> getsomething() 
     { 
       unique_ptr<A> myval; 
       myval.reset(new A); 
       return myval; 
     } 
}; 

但是當我評論本地unique_ptr<A> myval;編譯器會拋出錯誤。

shared_test.cpp: In member function ‘std::unique_ptr<A> A::getsomething()’: 
shared_test.cpp:12:10: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = A; _Dp = std::default_delete<A>]’ 
    return myval; 
     ^
In file included from /usr/include/c++/4.8/memory:81:0, 
       from shared_test.cpp:2: 
/usr/include/c++/4.8/bits/unique_ptr.h:273:7: error: declared here 
     unique_ptr(const unique_ptr&) = delete; 
    ^

我無法理解這個錯誤的含義。它是什麼?

+1

你明白爲什麼原始代碼會編譯嗎?因爲這也是一個有趣的問題,如果你不這樣做,這個答案可能會很長。 – juanchopanza

回答

3

您的本地變量myval正在隱藏類成員myval

When the criteria for elision of a copy operation are met and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue.

在你的第一種情況下,利用作爲myval如果它是一個rvalue創建返回的對象,因爲它是一個rvalue,它允許選擇move構造函數,如果有一個。

在第二種情況下,必須由一個副本,因此它直接調用copy構造,因爲unique_ptr對象不能被複制到的失敗,而你還沒有使用std::move,以確保編譯器調用構造函數move

+0

'myval'總是一個左值,而不是一個xvalue。有一個特殊的規則說,在這種情況下,您首先嚐試重載解析,就好像對象是由右值指定一樣,並不會改變這一事實。 –

+0

我已經更新了我的答案 – Jts

1

這意味着std::unique_ptr不能被複制。

讓您return語句舉動所有權,

return std::move(myval); 

或引用/指針回到原來的std::unique_ptr,雖然這將不轉讓所有權,是最有可能不是你想要的。

要理解爲什麼原來的OP代碼的工作,看Returning unique_ptr from functions

編輯:我認爲你的原身是這樣的:

// .. 
unique_ptr<A> getsomething() 
     { 
       return myval; 
     } 

從您最初詢問。

+0

那麼,爲什麼要編譯原始代碼呢? – juanchopanza

+0

@juanchopanza謝謝,我已經添加了一個鏈接到解決這個問題的另一個問題,如果這就是你的意思 –

+0

是的,這就是我的意思。 – juanchopanza