std::set 个独特的 ptr 范围插入

std::set of unique ptr range insert

我有 2 个数据结构,它们包含一组 unique_ptr,就像这样

std::vector<std::unique_ptr<Entity>> tmpEnts;
std::set<std::unique_ptr<Entity>> tmpSet;

我正在尝试执行如下所示的插入,但在编译时出现错误。我是智能指针的新手。

tmpSet.insert(tmpEnts.begin(), tmpEnts.end());

tmpEnts其实是一个简化,它其实驻留在一个std::map<uint, std::vector<std::unique_ptr<Entity>>> entities

编辑

错误占用了很多 space 但我认为这里有些东西我还不太明白。

/home/evgen/workspace/test/ecs/src/entity_manager.cpp:41:22:   required from here
/usr/include/c++/7.2.0/ext/new_allocator.h:136:4: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Entity; _Dp = std::default_delete<Entity>]’
  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/7.2.0/memory:80:0,
                 from /home/evgen/workspace/test/ecs/src/entity.hpp:4,
                 from /home/evgen/workspace/test/ecs/src/entity_manager.cpp:4:
/usr/include/c++/7.2.0/bits/unique_ptr.h:388:7: note: declared here
       unique_ptr(const unique_ptr&) = delete;
tmpSet.insert(tmpEnts.begin(), tmpEnts.end());

正在尝试将元素从 vector 复制到 set。编译失败,因为 unique_ptr 不可复制,必须移动它。您可以使用 move_iterators 来移动元素。

tmpSet.insert(
    std::make_move_iterator(tmpEnts.begin()),
    std::make_move_iterator(tmpEnts.end()));

请注意,在上述调用之后,您 vector 中的每个 Entity 对象都将被移出。

首先,我要说的是,如果您打算移动这些指针,unique_ptr 不是首选方式,而是 shared_ptr

其次,unique_ptr-s不能直接插入到一个adt中。他们必须搬家。所以为了让你的代码工作,你必须使用 std::move 语义:

std::set<std::unique_ptr<int>> tmpSet;

int main(int argc, char ** argv) {
    tmpSet.insert(std::move(std::make_unique<int>(1)));
    tmpSet.insert(std::move(std::make_unique<int>(2)));
}

或者,当从一个广告移动到另一个广告时:

std::vector<std::unique_ptr<int>> tmpEnts;
std::set<std::unique_ptr<int>> tmpSet;

int main(int argc, char ** argv) {
    tmpEnts.push_back(std::move(std::make_unique<int>(1)));
    tmpEnts.push_back(std::move(std::make_unique<int>(2)));

    auto from = std::make_move_iterator(tmpEnts.begin());
    auto to = std::make_move_iterator(tmpEnts.end());
    tmpSet.insert(from, to);
}