vector <std :: unique_ptr <t>的访问元素&gt;使用迭代器?

时间:2015-07-09 06:28:57

标签: c++ vector move unique-ptr

我有一个类成员变量

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指针,类,成员向量,任何成员函数或其他什么?

3 个答案:

答案 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移动到某处)