C++ – Copying std::unique_ptr’s value via dereferencing

cc++11unique-ptrvisual-c++-2012

I wrote the following code where I try to copy the value of unique_ptr object into a structure.

#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;
}

It pops up errors in Visual C++ 2012:

IntelliSense: no suitable user-defined conversion from "S" to "S"
exists
IntelliSense: no operator "=" matches these operands
operand types are: std::unique_ptr> = std::unique_ptr>
error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access
private member declared in class 'std::unique_ptr<_Ty>'

Unless I uncomment the lines where I attempted to define a copy constructor and =operator.
This gets rid of the compiler errors but not the IntelliSense errors. It compiles regardless of IntelliSense errors showing in error list.

So, why cannot it just use the default functions and compile with them? Am I doing the copy of value the right way? How should I define the copy constructor if it needs one?

Best Answer

The copy constructor is no implicitly generate because you have a user defined constructor, why is why your attempt to copy an S fails.

But still, unique_ptr are not copyable, only movable, so you can use a move constructor for S :

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

}

And call it :

S p = std::move(s); // Move s to p

Live demo

Related Topic