C++ 向量的访问元素<;标准::唯一性\u ptr<;T>&燃气轮机;使用迭代器?

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

以及一个成员函数,我想在其中使用
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); });