通过解除引用复制std :: unique_ptr的值

cpx*_*cpx 6 c++ unique-ptr c++11 visual-c++-2012

我编写了以下代码,我尝试将unique_ptr对象的值复制到结构中.

#include <iostream>
#include <memory>
using namespace std;

struct S {
    S(int X = 0, int Y = 0):x(X), y(Y){}

    // S(const S&) {}
    // S& operator=(const S&) { return *this; }

    int x;
    int y;
    std::unique_ptr<S> ptr;
};

int main() {
    S s;
    s.ptr = std::unique_ptr<S>(new S(1, 4));
    S p = *s.ptr; // Copy the pointer's value
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它在Visual C++ 2012中弹出错误:

IntelliSense:没有合适的用户定义从"S"到"S"的转换
IntelliSense:没有运算符"="匹配这些操作数操作数类型是:std :: unique_ptr> = std :: unique_ptr>
错误C2248:'std :: unique_ptr <_Ty> :: unique_ptr':无法访问类'std :: unique_ptr <_Ty>'中声明的私有成员

除非我取消注释我尝试定义复制构造函数和=运算符的行.这消除了编译器错误,但没有消除IntelliSense错误.无论错误列表中显示的IntelliSense错误如何,它都会编译.

那么,为什么不能只使用默认函数并用它们编译呢?我是以正确的方式做价值的副本吗?如果需要,我应该如何定义复制构造函数?

qua*_*dev 6

复制构造函数不会隐式生成,因为您有一个用户定义的构造函数,为什么复制的尝试S失败的原因.

但尽管如此,unique_ptr并不可复制,只有移动的,所以你可以使用一个移动构造函数S:

S(S&& other) : x(other.x), y(other.y), ptr(std::move(other.ptr))
{

}
Run Code Online (Sandbox Code Playgroud)

并称之为:

S p = std::move(s); // Move s to p
Run Code Online (Sandbox Code Playgroud)

现场演示