C++ 向量的访问元素<;标准::唯一性\u ptr<;T>&燃气轮机;使用迭代器?
我有一个类成员变量作为 向量v代码> 以及一个成员函数,我想在其中使用C++ 向量的访问元素<;标准::唯一性\u ptr<;T>&燃气轮机;使用迭代器?,c++,vector,move,unique-ptr,C++,Vector,Move,Unique Ptr,我有一个类成员变量作为 向量v 以及一个成员函数,我想在其中使用v元素的unique\u ptr元素,该元素由迭代器参数“寻址”。哪一个更好 void mem_fun(vector<std::unique_ptr<T> >::iterator it) { std::unique_ptr<T> p; p = std::move(*it); ... } void mem_-fun(vector::iterator it){ std::唯一
v
元素的unique\u ptr
元素,该元素由迭代器
参数“寻址”。哪一个更好
void mem_fun(vector<std::unique_ptr<T> >::iterator it) {
std::unique_ptr<T> p;
p = std::move(*it);
...
}
void mem_-fun(vector::iterator it){
std::唯一的ptr p;
p=标准::移动(*it);
...
}
或
void mem_-fun(vector::iterator it){
std::unique_ptr&p=*it;
...
}
据我所知,第二种方式似乎违反了
unique\u ptr
的“唯一性”。但是可以std::move()
move*它
(参考)?顺便问一下,谁真正拥有unique\u ptr
指针、类、成员向量、任何成员函数或其他什么?第一个版本拥有unique\u ptr
的目标,并将向量保留为空unique\u ptr
s。这不太可能是你想要的。第二个版本令人困惑。如果您只想访问由unique\ptr
s管理的对象而不影响所有权,只需使用删除引用操作符:
这里,取消引用(*it)
是取消引用迭代器,->
是取消引用唯一的\u ptr
请记住:unique\u ptr
的“唯一性”指的是它的所有权。没有什么可以说托管对象不能被许多非所有者访问。但是,根据应用程序的要求,由您决定谁拥有所有权
p = std::move(*it);
这意味着,p
现在拥有以前属于*it
的东西,而*it
不再拥有它(*)
事实上,以后使用*它
可能会导致未定义的行为,因为它已从
*后面的唯一\u ptr
属于向量。
事实上你改变了向量。我认为这不是你想要的,所以最好使用参考版本
[…]第二种方式似乎违反了“独特性”[…]
在这种情况下,唯一性意味着对象的单一所有者。当然,您可能对该对象的所有者(即指针)有多个引用
(*)这也意味着当p
超出范围时,对象将被销毁并解除分配。(除非您从p
某处移动)这包含了回答您问题的知识
unique\u ptr
实际上定义了一个“所有权证书”。此所有权不可复制。当您移动唯一\u ptr
时,这将有效地破坏存储在`向量'中的证书
因此,vector
拥有T
s
当您只想处理T
s时,您应该将函数声明为
void mem_fun(T& t) { ... }
并将解引用委托给另一个函数:
template<typename It, typename F>
void foreach_deref(It from, It to, F f) {
std::for_each(from, to, [&](decltype(*from) &pt) {
f(*pt);
}
}
foreach_deref(begin(v), end(v), [&](T& t) { mem_fun(t); });
您的函数是否仅访问T
对象?或者它真的需要迭代器,即必须访问多个T
s?它确实需要一个迭代器。那么unique\u ptr
的“所有权”是否意味着“设置”和“获取”唯一副本的权限?没有所有权但有引用的其他人可以“获取”但不能“设置”?复制另一个副本(例如调用push_back()
)也是一个“获取”操作?@WanxinGao不,这意味着谁可以控制它的生命周期。当所有者死亡时,托管对象也会死亡。好的!所以对于unique\u ptr
来说,任何人都有使用权(“get”和“set”),但只有一个人拥有所有权(?)@WanxinGao是的,没错。所有权可以转移,但只有一个所有者。一个未定义的行为?我认为使用*它
可能会将向量中的原始唯一\u ptr
设置为null
?只有取消对“从指针移动”的引用才会导致UB,因为在移动(*it)
之后,指针被设置为null ptr
。尽管仅仅是访问(通过*它)并不会改变任何事情。
template<typename It, typename F>
void foreach_deref(It from, It to, F f) {
std::for_each(from, to, [&](decltype(*from) &pt) {
f(*pt);
}
}
foreach_deref(begin(v), end(v), [&](T& t) { mem_fun(t); });