转移std :: vector的所有权的正确方式std :: unique_ptr< int> >到正在构建的类 [英] Proper way of transferring ownership of a std::vector< std::unique_ptr< int> > to a class being constructed
问题描述
转移 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 int
s: 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< int> >到正在构建的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!