C++ 迭代 unique_ptr 的容器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8237502/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:14:19  来源:igfitidea点击:

Iterating over a container of unique_ptr's

c++iteratorcontainersunique-ptr

提问by Dr DR

How does one access unique_ptr elements of a container (via an iterator) without taking ownership away from the container? When one gets an iterator to an element in the container is the element ownership still with the container? How about when one dereferences the iterator to gain access to the unique_ptr? Does that perform an implicit move of the unique_ptr?

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

I find I'm using shared_ptr a lot when I need to store elements in a container (not by value), even if the container conceptually owns the elements and other code simply wishes to manipulate elements in the container, because I'm afraid of not being able to actually access the unique_ptr elements in the container without ownership being taken from it.

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

Any insights?

任何见解?

采纳答案by Howard Hinnant

As long as you don't try to make a copy of the unique_ptr, you can just use it. You'll have to "double dereference" the iterator to get to the pointer's value, just as you would have to with shared_ptr. Here's a brief example:

只要您不尝试制作 的副本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);
}

If you do (accidentally) make a copy of the unique_ptr:

如果您(不小心)制作了以下内容的副本unique_ptr

Ptr p = v[0];

then you'll find out at compile time. It won't cause a run time error. Your use case is why container<unique_ptr<T>>was built. Things should just work, and if they don't, the problem appears at compile time instead of run time. So code away, and if you don't understand the compile time error, then ask another question back here.

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

回答by Pascal

With autoand the range-based for-loops of C++11 this becomes relatively elegant:

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

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

The reference &to the std::unique_ptravoids the copying and you can use the uniqe_ptrwithout dereferencing.

参考&std::unique_ptr避免了复制,你可以使用uniqe_ptr无解引用。