Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<A, std::__1::default_delete<A> >'

Tags:

c++

xcode

c++11

I'm constructing an object that takes a std::vector<std::unique_ptr<A> > as an argument. The constructor is defined like this

class B {
    std::vector <std::unique_ptr<A> > e_;

public:
    B(std::vector <std::unique_ptr<A> > e) : e_(std::move(e)){}

};

and then used as

std::vector <std::unique_ptr<A> > e;
B b(e);

and Xcode presents the error

error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<A, std::__1::default_delete<A> >'
:new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
                 ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`

Why is the error still persisting even though i am using std::move()?

EDIT: the error seems to vanish if i use B b(std::move(e)) instead of B b(e)), is there any way to move the move logic to the implementation of the function?

like image 623
Abhishek Avatar asked Sep 27 '16 12:09

Abhishek


1 Answers

Your constructor argument is pass by value which will make a copy, but you cannot copy a std::unique_ptr. Passing by reference should work:

class B {
    std::vector <std::unique_ptr<float> > e_;

public:
    B(std::vector <std::unique_ptr<float> >& e) : e_(std::move(e)){}

};

But...I agree with the other comments that this is bad design. If you want B to own e but also want to manipulate e outside of B then it should be a public member, no fancy constructor needed:

class B {
public:
    std::vector <std::unique_ptr<float> > e_;
};
like image 185
atb Avatar answered Oct 29 '22 23:10

atb