我有一个类成员变量
vector<std::unique_ptr<T> > v;
和一个成员函数,我想使用unique_ptr
的{{1}}元素&#34;已解决&#34;通过v
参数。哪一个更好?
iterator
或者
void mem_fun(vector<std::unique_ptr<T> >::iterator it) {
std::unique_ptr<T> p;
p = std::move(*it);
...
}
据我所知,似乎第二种方式违反了&#34;唯一性&#34; void mem_fun(vector<std::unique_ptr<T> >::iterator it) {
std::unique_ptr<T>& p = *it;
...
}
。但unique_ptr
可以移动std::move()
(参考)吗? BTW,谁真正拥有*it
指针,类,成员向量,任何成员函数或其他什么?
答案 0 :(得分:1)
第一个版本取得unique_ptr
目标的所有权,并将向量留空unique_ptr
s。这不太可能是你想要的。第二个版本令人困惑。如果您只想访问由unique_ptr
管理的对象而不影响所有权,只需使用derererence运算符:
(*it)->someMethodOfT();
此处,取消引用(*it)
将取消引用迭代器,->
将取消引用unique_ptr
。
请记住:unique_ptr
的“唯一性”是指其所有权。没有什么可说的,许多非所有者无法访问托管对象。但是,由您来决定谁拥有所有权,具体取决于您的申请要求。
答案 1 :(得分:1)
此post from Herb Sutter包含回答您问题的知识。
unique_ptr
实际上定义了所有权证书&#39;。此所有权无法复制。当你move
unique_ptr
时,这会有效地破坏存储在`vector中的证书。
因此,vector<unique_ptr<T>>
拥有 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); });
答案 2 :(得分:0)
p = std::move(*it);
这意味着,p
现在拥有*it
之前拥有的内容,*it
不再拥有它(*)。
事实上,以后使用*it
可能会导致未定义的行为,因为它已被移出。
unique_ptr
后面的*it
由向量拥有。
所以事实上你改变了你的矢量。我认为这不是你想要的,所以最好使用参考版本。
[...]似乎第二种方式只是违反了“独特性”[...]
在这种情况下,唯一性意味着对象的单个所有者。您当然可以对此对象的所有者(指针)进行多次引用。
(*)这也意味着当p
超出范围时,对象将被销毁并解除分配。 (除非你从p
移动到某处)