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