Although having worked several years with C#, getting things done in C++ is sometime still difficult for me. I fully embrace the usage of smart pointers, but now I'm facing the following puzzle
I have a struct Foo, e.g.
struct Foo
{
Foo(std::unique_ptr<Bar> bar) : m_myBar(std::move(bar)) {}
private:
std::unique_ptr<Bar> m_myBar;
};
In a different class, I want to have a vector containing instances of Foo, but the following line
std::vector<Foo> m_Foos;
yields compile errors saying that the copy constructor is deleted. In the SO thread "Why can I not push_back a unique_ptr into a vector?" an explanation as well as a remedy is given. However, there the question concerns a vector of unique pointers whereas I have a vector of structs containing a unique pointer. The suggested solution is to use move semantics, but how does that apply in my situation? Or should I be doing something else?
std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope. The object is disposed of, using the associated deleter when either of the following happens: the managing unique_ptr object is destroyed.
You can use make_unique to create a unique_ptr to an array, but you cannot use make_unique to initialize the array elements. C++ Copy. // Create a unique_ptr to an array of 5 integers. auto p = make_unique<int[]>(5); // Initialize the array. for (int i = 0; i < 5; ++i) { p[i] = i; wcout << p[i] << endl; }
std::make_uniqueConstructs an object of type T and wraps it in a std::unique_ptr. 1) Constructs a non-array type T . The arguments args are passed to the constructor of T . The function does not participate in the overload resolution if T is an array type.
As you say, m_Foos is actually a data member of another class (I'll call it FooHolder). If you didn't provide a copy constructor for FooHolder, the compiler will generate one automatically. That copy constructor will call the copy constructors of all data members of FooHolder, including m_Foos. Of course, the copy constructor of std::vector<Foo> contains a compilation error, since Foo is not copyable. This is probably why you're getting the error.
You'll have to provide an appropriate copy constructor for FooHolder, if you are able to and want that class to be copyable. Otherwise, you can just declare a move constructor (possibly defaulted), which will make the copy constructor deleted:
struct FooHolder
{
FooHolder(FooHolder&&) = default;
private:
std::vector<Foo> m_Foos;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With