2013-02-14 168 views
0

我嘗試運行這段代碼從第一矢量到另一個移動的unique_ptr的,在拷貝構造函數:誤差在移動的std ::的unique_ptr

class Text 
{ 
    struct paragraph 
    { 
     int index; 
     string text; 
    }; 

    vector<unique_ptr<paragraph>> paragraphs; 

public: 

    Text() 
    { 
     paragraphs.push_back(unique_ptr<paragraph>(new paragraph)); 
    } 

    Text(const Text & t) 
    { 
     for(int i = 0; i < (int)t.paragraphs.size(); i++) 
     { 
      paragraphs.push_back(move(t.paragraphs[i])); 
     } 
    } 
}; 

,我得到這個錯誤:

1>c:\program files\microsoft visual studio 10.0\vc\include\xmemory(208): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>' 
1>   with 
1>   [ 
1>    _Ty=Text::paragraph 
1>   ] 
// Etc. 
+1

** unique ** _ptr。 'vector :: push_back'製作一個副本。但'unique_ptr'沒有公開的拷貝文件。 – StoryTeller 2013-02-14 10:21:40

+0

那麼這是怎麼回事? – user1544067 2013-02-14 10:22:40

+1

@StoryTeller:不一定,重載'push_back'需要右值引用。 – interjay 2013-02-14 10:22:43

回答

5

你的代碼有幾個錯誤。

首先,您不能從const&移動,這也適用於const&的成員。運動是破壞性的;你應該只從&&移動。你的拷貝構造函數應該是拷貝;如果你不想要一個拷貝構造函數,那麼= delete它或任何你的編譯器允許的。其次,假設你爲合適的移動構造函數採取了Test &&,則不應該像這樣移動每個元素。相反,移動矢量到新的一個是這樣的:

Text(Text && t) : paragraphs(std::move(t.paragraphs)) {} 

第三,你應該只寫這個函數假設你選擇的編譯器不支持自動生成move構造函數(即:是的Visual Studio)。如果它確實支持它,那麼不應該寫一個。讓編譯器做它的工作。

+1

+1,它也修復'(int)t.paragraphs.size()'bug – billz 2013-02-14 10:35:38

0
Text(const Text & t) 
{ 
    for(int i = 0; i < (int)t.paragraphs.size(); i++) 
    { 
     paragraphs.push_back(move(t.paragraphs[i])); 
    } 
} 

在此構造t是常量,所以t.paragraphs[i]給出一個const左值參照unique_ptr

move(t.paragraphs[i])變成const 右值引用,但它仍然是常量。移動構造函數需要非常量右值引用,因此不可行,所以刪除的副本構造函數是最佳匹配項。你不應該試圖在拷貝構造函數中移動t的內容,這是移動構造函數的用途。

你也應該說std::move不只是move,以防止ADL發現錯誤的舉動。