简体   繁体   English

移动std :: unique_ptr时出错

[英]error in moving std::unique_ptr

I try to run this code to move the unique_ptr's from the first vector to another, in the copy constructor: 我尝试运行以下代码以将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]));
        }
    }
};

and i got this error: 我得到了这个错误:

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.

There are several things wrong with your code. 您的代码有几处错误。

First, you cannot move from a const& , and this applies to members of a const& too. 首先,您不能从const&移开,这也适用于const&成员。 Movement is destructive; 运动具有破坏性; you should only move from a && . 您只能从&&移开。 Your copy constructor should copy ; 你的复制构造器应该复制 ; if you don't want a copy constructor, then = delete it or whatever your compiler allows. 如果您不想要复制构造函数,则= delete它或编译器允许的任何形式。

Second, assuming you took a Test && for a proper move constructor, you should not move each element like that. 其次,假设您为适当的move构造函数进行了Test && ,则不应该这样移动每个元素。 Instead, move the vector into the new one like this: 而是将向量移到新的向量中,如下所示:

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

Third, you should only write this function assuming that your compiler of choice doesn't support automatically generated move constructors (ie: is Visual Studio). 第三,您只应在假设您选择的编译器不支持自动生成的move构造函数(即Visual Studio)的情况下编写此函数。 If it does support it, you shouldn't write one at all . 如果它支持它,那么您根本不应该编写一个 Let the compiler do it's job. 让编译器完成任务。

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

In this constructor t is const, so t.paragraphs[i] gives a const lvalue reference to a unique_ptr . 在此构造函数中, t为const,因此t.paragraphs[i]给出了对unique_ptr的const左值引用。

move(t.paragraphs[i]) turns that into a const rvalue reference, but it's still const. move(t.paragraphs[i])将其转换为const rvalue引用,但仍为const。 The unique_ptr move constructor needs a non-const rvalue reference, so isn't viable, so the deleted copy constructor is the best match. unique_ptr move构造函数需要一个非常量右值引用,因此不可行,因此删除的副本构造函数是最佳匹配。 you shouldn't be trying to move the contents of t in a copy constructor, that's what move constructors are for. 您不应该尝试在副本构造函数中移动t的内容,这就是move构造函数的作用。

You should also say std::move not just move , to prevent ADL finding the wrong move. 您还应该说std::move不只是move ,以防止ADL找到错误的动作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM