Question

I'm trying to make a std list that will hold a list of classes that contain a unique pointer. I keep getting an error that says attempting to reference a deleted function.

I understand that the problem is that unique pointers don't have an assignment operator and list is trying to call it, but I can't figure out a way around this.

Here is the code for the class that holds the pointer:

class ptr_hold
{
public:
    ptr_hold(std::list<int>& _lst);
    std::list<int>* get_list();
private:
    std::unique_ptr<std::list<int>> num_list;
};

ptr_hold::ptr_hold(std::list<int>& _lst)
{
    num_list = std::unique_ptr<std::list<int>>(new std::list<int>(_lst));
}

Here is the example code trying to do the assigment:

list<int> lst;
for (int i = 0; i < 5; i++)
{
    lst.push_back(i);
}
ptr_hold ph = ptr_hold(lst);

list<ptr_hold> ph_list;
ph_list.push_back(ph); //error
ph_list.push_back(move(ph)); //error

How do I handle this?

Was it helpful?

Solution

Well, there is a good chance that you are using VS, since it doesn't automagically generate move member functions for you. (Otherwise ph_list.push_back(move(ph)) would work.)

The unique_ptr does have move-assignment operator, which implies ownership transfer. To call move-assignment operator (or move constructor for that matter) you need to work with rvalue. (T&&, where T is not meant as template here, as that invokes something a bit different) To obtain a rvalue, you either have to work with a temporary (such as a return value from a function) or you have to manually cast lvalue to rvalue. This is done via std::move (to signify intent) or a bit more wordy static_cast.

To solve this, either use emplace_back or declare proper constructors manually, and use either emplace_back or push_back(move()).

---edit---
Note: emplace_back probably shouldn't require move-assignment constructor to work, but you will run into trouble when trying to extract the object from the list.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top