std::set 唯一 ptr 范围插入
Posted
技术标签:
【中文标题】std::set 唯一 ptr 范围插入【英文标题】:std::set of unique ptr range insert 【发布时间】:2017-09-27 23:05:43 【问题描述】:我有 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;
【问题讨论】:
疯狂猜测我假设您的编译器尝试使用复制.insert()
范围,如果在 std::unique_ptr
上执行它是禁止的
是的,我也有类似的想法,我尝试使用 std::move。得到同样的错误。
【参考方案1】:
tmpSet.insert(tmpEnts.begin(), tmpEnts.end());
正在尝试将元素从 vector
复制到 set
。编译失败,因为unique_ptr
不可复制,必须移动。您可以改用move_iterator
s 来移动元素。
tmpSet.insert(
std::make_move_iterator(tmpEnts.begin()),
std::make_move_iterator(tmpEnts.end()));
请注意,在上述调用之后,vector
中的每个 Entity
对象都将被移出。
【讨论】:
是的,我知道 unique_ptr 的独占所有权。我不知道make_move_iterator。多谢! :D 有效 是的。use of deleted function 'unique_ptr(const std::unique_ptr&)'
"你不能复制 unique_ptr"
他不是摔倒了吗?哈哈【参考方案2】:
首先,让我说,如果您打算移动这些指针,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);
【讨论】:
当我使用向量的迭代器将数据复制到集合时,我明白了我所说的那部分,这就是我迷路的地方。 @EvgenyDanilenko,我添加了将数据从向量复制到集合的缺失实现。 是的,我不知道 std::make_move_iterator。我对 c++ 也比较陌生,但对编程并不陌生。通过构建一个简单的 2d 引擎开始学习 c++。目前正在实现我的 ecs 架构。谢谢你的回答:)以上是关于std::set 唯一 ptr 范围插入的主要内容,如果未能解决你的问题,请参考以下文章
插入 std::set<std::tuple<std::string, ...>> 时重复