[英]Access elements of vector<std::unique_ptr<T> > using an iterator?
我有一个类成员变量
vector<std::unique_ptr<T> > v;
和一个成员函数,我想使用由iterator
参数“寻址”的v
的unique_ptr
元素。 哪一个更好?
void mem_fun(vector<std::unique_ptr<T> >::iterator it) {
std::unique_ptr<T> p;
p = std::move(*it);
...
}
要么
void mem_fun(vector<std::unique_ptr<T> >::iterator it) {
std::unique_ptr<T>& p = *it;
...
}
据我所知,似乎第二种方式违反了unique_ptr
的“唯一性”。 但是std::move()
移动*it
吗(引用)? 顺便说一句,谁真正拥有unique_ptr
指针,类,成员向量,任何成员函数或其他东西?
第一个版本拥有unique_ptr
目标的所有权,而向量则留有空白unique_ptr
。 这不太可能是您想要的。 第二个版本令人困惑。 如果您要做的就是在不影响所有权的情况下访问unique_ptr
管理的对象,则只需使用de-erererence运算符:
(*it)->someMethodOfT();
在这里,取消引用(*it)
将取消对迭代器的引用,而->
将取消对unique_ptr
的引用。
请记住: unique_ptr
的“唯一性”是指其所有权。 没什么好说的,许多非所有者不能访问托管对象。 但是,取决于应用程序的要求,由您决定谁拥有所有权。
Herb Sutter的这篇文章包含了回答您的问题的知识。
unique_ptr
实际上定义了一个“所有权证书”。 此所有权不可复制 。 当您move
unique_ptr
,这有效地破坏了存储在`vector中的证书。
因此, vector<unique_ptr<T>>
拥有 T
当您只想使用T
进行填充时,应将函数声明为
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); });
p = std::move(*it);
这意味着, p
现在拥有*it
之前拥有的东西,并且*it
不再拥有(*)。
实际上,此后使用*it
可能会导致不确定的行为,因为它已被移出。
*it
后面的unique_ptr
由向量拥有。 因此,实际上您更改了向量。 我认为这不是您想要的,所以最好使用参考版本。
[...]似乎是违反“独特性”的第二种方法[...]
在这种情况下,唯一性表示对象的单一所有者。 当然,您可能对该对象的所有者(即指针)具有多个引用。
(*)这也意味着,当p
超出范围时,对象将被销毁并释放。 (除非您从p
移到某个地方)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.