繁体   English   中英

向量的访问元素 <std::unique_ptr<T> &gt;使用迭代器?

[英]Access elements of vector<std::unique_ptr<T> > using an iterator?

我有一个类成员变量

vector<std::unique_ptr<T> > v;

和一个成员函数,我想使用由iterator参数“寻址”的vunique_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM