转移std :: vector的所有权的正确方式std :: unique_ptr< int> >到正在构建的类 [英] Proper way of transferring ownership of a std::vector< std::unique_ptr< int> > to a class being constructed

查看:141
本文介绍了转移std :: vector的所有权的正确方式std :: unique_ptr< int> >到正在构建的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



下面是我想要做的代码表示。我意识到这是不正确的(不会编译),违反唯一性是否通过值或引用传递给构造函数的向量。我想要Foo成为向量的新所有者,并希望调用函数放弃所有权。我需要构造函数获取 std :: unique_ptr< std :: vector< std :: unique_ptr< int> > >

  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;
}

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

解决方案

std :: unique_ptr< T> - 可复制但可移动类型。在 std:vector< T> 中具有仅移动类型使得 std :: vector< T> move - 只是。要使编译器自动移动对象,您需要具有用于移动构造或移动分配的r值。在你的构造函数中,对象 vecOfIntPtrsOwnedByCaller 是一个l值,尽管它的名称已经拥有 int s:当调用者创建对象时,它们从调用者偷了。要从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值的引用,但这不是必须的。



注意,你可以构造类型 Foo 只能从可以绑定到r值的东西,例如:

  int main (){
Foo f0(std :: vector< std :: unique_ptr< int>>()); // OK
std :: vector< std :: unique_ptr< int>> v;
Foo f1(v); v // ERROR:使用l值
Foo f2 {v}; v // ERROR:使用l值
Foo f3 = v; //错误:使用l值
Foo f4(std :: move(v)); // OK:假装v是一个r值
}


What is the proper way of transferring ownership of a std::vector<unique_ptr<int> > to a class being constructed?

Below is a code representation of what I want to do. I realize it is not correct (won't compile) and violates "uniqueness" whether I pass the vector to the constructor by value or by reference. I want Foo to be the new owner of the vector, and want the calling function to relinquish ownership. Do I need the constructor to take a std::unique_ptr<std::vector<std::unique_ptr<int> > > to do this?

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;
}

Any help would be much appreciated - I've scoured the net looking for the correct way to do this. Thanks!

解决方案

std::unique_ptr<T> is a non-copyable but movable type. Having a move-only type in a std:vector<T> make the std::vector<T> move-only, too. To have the compiler automatically move objects, you need to have an r-value for move-construction or move-assignment. Within your constructor the object vecOfIntPtrsOwnedByCaller is an l-value, although one which, despite its name, already owns the pointed to ints: they got "stolen" from the caller when the caller created the object. To move from an l-value, you need to use std::move() (or something equivalent):

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

or, preferable

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

The latter approach avoid first default-constructing the member and then move-assigning to it and, instead, move-constructs the member directly. I guess, I would also make the argument an r-value reference but this isn't necessary.

Note, that you can construct objects of type Foo only from something which can be bound to an r-value, e.g.:

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
}

这篇关于转移std :: vector的所有权的正确方式std :: unique_ptr&lt; int&gt; &gt;到正在构建的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆