我尝试运行此代码,以便在复制构造函数中将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.
答案 0 :(得分:5)
您的代码存在一些问题。
首先,您无法从const&
移动,这也适用于const&
的成员。运动是破坏性的;你应该只从&&
移动。您的复制构造函数应该复制;如果您不想要复制构造函数,那么= delete
或者编译器允许的任何内容。
其次,假设您使用Test &&
作为正确的移动构造函数,则不应该像这样移动每个元素。相反,将矢量移动到新的矢量中:
Text(Text && t) : paragraphs(std::move(t.paragraphs)) {}
第三,您应该只编写此函数,假设您选择的编译器不支持自动生成的移动构造函数(即:是Visual Studio)。如果它支持它,你根本不应该写一个。让编译器完成它的工作。
答案 1 :(得分:0)
Text(const Text & t)
{
for(int i = 0; i < (int)t.paragraphs.size(); i++)
{
paragraphs.push_back(move(t.paragraphs[i]));
}
}
在此构造函数t
中是const,因此t.paragraphs[i]
给出unique_ptr
的常量值引用。
move(t.paragraphs[i])
将其转换为const rvalue 引用,但它仍然是const。 unique_ptr
移动构造函数需要非const rvalue引用,因此不可行,因此删除的复制构造函数是最佳匹配。你不应该试图在复制构造函数中移动t
的内容,这就是构造函数的用途。
您还应该说std::move
而不仅仅是move
,以防止ADL找到错误的举动。