转移std :: vector所有权的正确方法<的std ::的unique_ptr< INT> >到正在建造的一个类

时间:2013-08-16 21:13:00

标签: c++ c++11 stdvector unique-ptr ownership

std::vector<unique_ptr<int> >的所有权转移到正在构建的班级的正确方法是什么?

下面是我想要做的代码表示。我意识到它不正确(不会编译)并违反“唯一性”,无论我是通过值还是通过引用将向量传递给构造函数。我希望Foo成为向量的新所有者,并希望调用函数放弃所有权。我是否需要构造函数来std::unique_ptr<std::vector<std::unique_ptr<int> > >执行此操作?

foo.h中

class Foo
{
public:
  Foo(vector<std::unique_ptr<int> > vecOfIntPtrsOwnedByCaller);

private:
  vector<std::unique_ptr<int> > _vecOfIntPtrsOwnedByFoo;
}

Foo.cpp中

Foo::Foo(std::vector<std::unique_ptr< int> > vecOfIntPtrsOwnedByCaller)
{
    _vecOfIntPtrsOwnedByFoo = vecOfIntPtrsOwnedByCaller;
}

任何帮助都会非常感激 - 我已经在网上搜寻正确的方法来做到这一点。谢谢!

1 个答案:

答案 0 :(得分:21)

std::unique_ptr<T>是一种不可复制但可移动的类型。在std:vector<T>中使用仅限移动类型也会使std::vector<T>仅移动。要让编译器自动移动对象,您需要为移动构造或移动分配设置r值。在你的构造函数中,对象vecOfIntPtrsOwnedByCaller是一个l值,尽管它尽管名称已经拥有指向int的一个值:当调用者创建对象时,它们从调用者那里“被盗”了。要从l值移动,您需要使用std::move()(或类似的东西):

Foo::Foo(std::vector<std::unique_ptr<int>> vecOfIntPtrsOwnedByCaller)
{
    _vecOfIntPtrsOwnedByFoo = std::move(vecOfIntPtrsOwnedByCaller);
}

或者,首选

Foo::Foo(std::vector<std::unique_ptr<int>> vecOfIntPtrsOwnedByCaller)
    : _vecOfIntPtrsOwnedByFoo(std::move(vecOfIntPtrsOwnedByCaller))
{
}

后一种方法避免首先默认构造成员,然后移动分配给它,而是移动 - 直接构造成员。我想,我也会把参数作为r值引用,但这不是必需的。

请注意,您只能从可以绑定到r值的内容构造Foo类型的对象,例如:

int main() {
    Foo f0(std::vector<std::unique_ptr<int>>()); // OK
    std::vector<std::unique_ptr<int>> v;
    Foo f1(v); v// ERROR: using with an l-value
    Foo f2{v}; v// ERROR: using with an l-value
    Foo f3 = v; // ERROR: using with an l-value
    Foo f4(std::move(v)); // OK: pretend that v is an r-value
}