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

Feb 11, 2020 at 7:35pm
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.
Feb 11, 2020 at 7:57pm
This works:

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

Last edited on Feb 11, 2020 at 7:57pm
Feb 11, 2020 at 9:10pm
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
Feb 11, 2020 at 10:45pm
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 

Feb 13, 2020 at 2:38pm
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.