如何从STL容器中获取仅移动类型?

时间:2016-10-01 18:56:22

标签: c++ c++11 memory containers move

我们以std::unordered_set std::unique_ptr<T>为例。我可以在其他位置移动该组的元素吗?

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

int main()
{
    std::unordered_set<std::unique_ptr<int>> mySet;

    mySet.insert(std::make_unique<int>(1));
    mySet.insert(std::make_unique<int>(2));
    mySet.insert(std::make_unique<int>(3));

    std::vector<std::unique_ptr<int>> myVector;

    for (auto&& element : mySet)
    {
        std::cout << *element << std::endl;
        //myVector.push_back(element); won't compile as you can only get a const ref to the key
    }
}

我有一个非常实用的代码示例,我希望这样做,但我减少使用std::shared_ptr。你知道另一个(更好吗?)的选择吗?

1 个答案:

答案 0 :(得分:9)

在C ++ 03,C ++ 11和C ++ 14中,不是直接的。您必须将类型更改为:

layout :: forall a. a -> String

有了这个,你可以写:

template <class T>
struct handle {
    mutable std::unique_ptr<T> owning_ptr;
    T* observing_ptr; // enforce that observing_ptr == owning_ptr.get() on construction

    // define operator<, hash, etc. in terms of the observing ptr
};

这仍然是明确定义的行为,因为我们并没有弄乱任何容器内部 - 观察指针在std::unordered_set<handle<int>> mySet; // initialize as appropriate for (auto& elem : mySet) { myVector.push_back(std::move(elem.owning_ptr)); } mySet.clear(); 的末尾仍然有效,刚才{{1}相反拥有它。

在C ++ 17中,我们可以在extract()的帮助下直接更简单地执行此操作:

clear()