36

如何访问容器的 unique_ptr 元素(通过迭代器)而不剥夺容器的所有权?当一个人获得容器中元素的迭代器时,元素所有权仍然在容器中吗?当一个人取消引用迭代器以获得对 unique_ptr 的访问时怎么样?这会执行 unique_ptr 的隐式移动吗?

我发现当我需要将元素存储在容器中(而不是按值)时,我经常使用 shared_ptr,即使容器在概念上拥有元素并且其他代码只是希望操纵容器中的元素,因为我害怕如果没有从容器中获取所有权,则无法实际访问容器中的 unique_ptr 元素。

有什么见解吗?

4

2 回答 2

67

使用autoC++11 的基于范围的 for 循环,这变得相对优雅:

std::vector< std::unique_ptr< YourClass >> pointers;
for( auto&& pointer : pointers ) {
    pointer->functionOfYourClass();
}

对 的引用&避免std::unique_ptr了复制,您可以在uniqe_ptr不取消引用的情况下使用。

于 2014-12-01T15:05:45.717 回答
22

只要您不尝试制作 的副本unique_ptr,您就可以使用它。您必须“双重取消引用”迭代器才能获得指针的值,就像您必须使用shared_ptr. 这是一个简短的例子:

#include <vector>
#include <memory>
#include <iostream>

template <class C>
void
display(const C& c)
{
    std::cout << '{';
    if (!c.empty())
        std::cout << *c.front();
    for (auto i = std::next(c.begin()); i != c.end(); ++i)
        std::cout << ", " << **i;
    std::cout << "}\n";
}

int main()
{
    typedef std::unique_ptr<int> Ptr;
    std::vector<Ptr> v;
    for (int i = 1; i <= 5; ++i)
        v.push_back(Ptr(new int(i)));
    display(v);
    for (auto i = v.begin(); i != v.end(); ++i)
        **i += 2;
    display(v);
}

如果您(不小心)复制以下内容unique_ptr

Ptr p = v[0];

然后你会在编译时发现。它不会导致运行时错误。您的用例就是container<unique_ptr<T>>构建的原因。事情应该可以正常工作,如果没有,问题就会出现在编译时而不是运行时。所以代码离开,如果你不理解编译时错误,然后在这里问另一个问题。

于 2011-11-23T15:07:23.017 回答