如何从STL容器中获取仅移动类型? [英] How to get a move-only type out of a STL container?

查看:63
本文介绍了如何从STL容器中获取仅移动类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们以std::unique_ptr<T>std::unordered_set为例.我可以将集合中的元素移到其他地方吗?

Let's consider an std::unordered_set of std::unique_ptr<T> as an example. Can I move an element of the set elsewhere ?

#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.您知道另一种(更好的?)替代方法吗?

I have a very practical example of code where I would like to do this but am reduced to use a std::shared_ptr. Do you know of another (better ?) alternative ?

推荐答案

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

In C++03, C++11, and C++14, not directly. You'd have to change the type to be something like:

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
};

使用此代码,您可以编写:

With this, you can write:

std::unordered_set<handle<int>> mySet;
// initialize as appropriate

for (auto& elem : mySet) {
    myVector.push_back(std::move(elem.owning_ptr));        
}
mySet.clear();

这仍然是定义明确的行为,因为我们不会弄乱任何容器内部结构-观察指针在clear()的末尾仍然有效,只是现在myVector拥有它.

This will still be well-defined behavior because we're not messing with any of the container internals - the observing pointer will still be valid through the end of the clear(), just now myVector owns it instead.

在C ++ 17中,我们可以借助

In C++17, we can do this directly and more simply with the help of extract():

for (auto it = mySet.begin(); it != mySet.end();  
{
    std::cout << **it << std::endl;
    myVector.push_back(std::move(
        mySet.extract(it++).value()));
}

这篇关于如何从STL容器中获取仅移动类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆