Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can an rvalue be moved into a shared_ptr

Is it possible to 'move' an rvalue into a shared_ptr. All the methods which I've tried so far result in a copy.

My desired usage pattern is:

class Element {
public:
    Element(const string &);
    Element(const Element &) = delete; //delete copy constructor
    // ...
};

class MyCollectionOfElements {
public:
    void add(Element &&); // add by rvalue
    // ...
protected:
    vector<shared_ptr<Element>> elements;
};

MyCollectionOfElements elements;
elements.add(Element("something"));

There are reasons why I want this pattern, and understand that there are alternative patterns which naturally work (e.g. passing the new Element as a pointer rather than an rvalue).

My current suspicion is that the incoming rvalue is on the stack, whilst I need to have it on the heap to store it in a shared_ptr, therefore a copy is inevitable.

like image 743
Elliot Woods Avatar asked Feb 24 '16 13:02

Elliot Woods


1 Answers

Yes:

void add(Element && e)
{
    elements.push_back(std::make_shared<Element>(std::move(e)));
}

You also have to make sure your class actually has a move constructor:

class Element
{
public:
    Element(Element &&) = default;
    // ...
};

By declaring a copy constructor, you inhibit the implicit declaration of a move constructor, so you need to declare it explicitly.

like image 90
Kerrek SB Avatar answered Oct 01 '22 10:10

Kerrek SB