error use of deleted function - when pushing back a class with a vector<unique_ptr<base>> member

Disclaimer; I realize some users are against "using namespace std;" and I don't use it in my actual code, I just thought it was more clear for the example.

Most of the code is pretty straight forward. I have a vector<Base> that can hold a list of pointers to derived classes to avoid slicing. One of those derived classes actually holds a vector<Base> itself. The problem comes when I try to push this class (called "DerivedArray" in the code below) into another vector<Base>.

if I comment out the "derived_items" member code I can push_back without problems.

http://coliru.stacked-crooked.com/a/3e14fb946d912ba2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <stdio.h>
#include <vector>
#include <iostream>
#include <memory>

using namespace std;

class Base {};

class Derived : public Base {};

class DerivedArray : public Base {
    public:
    DerivedArray(vector<unique_ptr<Base>>& vector) {
        derived_items = move(vector);
    };
    
    private:
    vector<unique_ptr<Base>> derived_items;
};


int main()
{   
    Derived d1;
    vector<unique_ptr<Base>> items;
    items.push_back(make_unique<Derived>(d1));
    
    DerivedArray da{items}; 
    
    // re-use items, which is now empty after the elements have been moved in DerivedArray's constructor
    items.push_back(make_unique<DerivedArray>(da)); // error

    return 0;
}


Why does this not work?

I have a hunch that there is somewhere a copy going on inside "make_unique()" that violates the uniqueness of the "unique_ptr"'s stored "derived_items", but I can't reason why because the function name suggests I get a unique reference to my DerivedArray "da".

Note that I'm not very proficient in plowing through the big list of errors of the template functions.

Thanks in advance.
This works:

 
    items.push_back(make_unique<DerivedArray>(move(da)));

Last edited on
Could you please elaborate why this works/is needed?

I'm missing the logic as to why I'd need to move() the DerivedArray object. Thanks
Could you please elaborate why this works/is needed?

make_unique creates a copy of da, which contains unique_ptr's.
You could try this instead:

1
2
    // DerivedArray da{items};
    items.push_back(make_unique<DerivedArray>(items)); // construct in place 

Unique_ptrs do not have a copy constructor. They cannot be copied, only moved. Think about it, if a unique_ptr could be copied (which means a single resource can have more than one pointer pointing to it), that wouldn't make the unique_ptr very "unique", would it?
Topic archived. No new replies allowed.