2013-02-14 123 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发现错误的举动。