std :: set的唯一ptr范围插入

时间:2017-09-27 23:05:43

标签: c++ c++11 unique-ptr

我有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

修改

错误占用了很多空间,但我认为这里有一些我还不太了解的东西。

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

2 个答案:

答案 0 :(得分:4)

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

正在尝试将元素从vector复制到set。由于unique_ptr不可复制,因此无法编译,因此必须将其移动。您可以使用move_iterator来移动元素。

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

请注意,完成上述调用后,Entity中的每个vector对象都会被移出。

答案 1 :(得分:1)

首先,请允许我说,如果您计划移动这些指针,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)));
}

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

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