I have a class implemented using the PImpl Ideom:
class FooImpl {};
class Foo
{
unique_ptr<FooImpl> myImpl;
public:
Foo();
~Foo();
};
And now I want to put this into a std::vector
void Bar()
{
vector<Foo> testVec;
testVec.resize(10);
}
But when I do that, I get a compiler error (VC++ 2013)
error C2280: 'std::unique_ptr>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : attempting to reference a deleted function
I get the same error with testVec.emplace_back();
and testVec.push_back(std::move(Foo()));
(As a workaround, using vector<unique_ptr<Foo>>
seems to work, but I don't understand why the code above doesn't work.)
Working example: http://coliru.stacked-crooked.com/a/b274e1209e47c604
Since
std::unique_ptr
is not copyable, classFoo
does not have a valid copy constructor.You could either deep copy or use a move constructor:
Live example: https://ideone.com/HYtPMu
So what happens is that the
vector
template tries to access the copy constructor of theFoo
class. You have not provided one, so the compiler tries to generate a default implementation that calls the copy constructor on all members. Since thestd::unique_ptr
does not have a copy constructor from anotherstd::unique_ptr
(which is logical because it does not know how to copy the object) the compiler cannot generate the assignment operator forFoo
and it fails. So what you can do is provide a copy constructor for theFoo
class and decide how to handle the pointer: