可以将右值移动到shared_ptr中

时间:2016-02-24 13:23:10

标签: c++ c++11 rvalue-reference

是否可以将rvalue“移动”到shared_ptr。到目前为止,我尝试过的所有方法都会产生副本。

我想要的使用模式是:

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"));

我有理由想要这种模式,并了解有其他模式可以自然地起作用(例如,将新的Element作为指针传递而不是rvalue)。

我当前的怀疑是传入的rvalue在堆栈上,而我需要在堆上将它存储在shared_ptr中,因此副本是不可避免的。

2 个答案:

答案 0 :(得分:10)

是:

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

您还必须确保您的班级 移动构造函数:

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

通过声明复制构造函数,可以禁止移动构造函数的隐式声明,因此需要明确声明它。

答案 1 :(得分:0)

猜猜你误解了运动语义的概念。您必须将指针传递给智能指针,指针可以具有任何类型 - 左值/右值

    void f(A *&&p) {}

接受rvalue ref指向A的指针的函数;但是p仍然是左值,它具有指针的类型r值引用, 所以你必须“施放”(std :: move - 什么都不做只是将l值转换为r值) 的std :: shared_ptr的(标准::移动(P));

    A *g() { return new A;}
    A *a;
    f(a);//error        
    f(g());//works fine
    f(new A());//also fine