将unique_ptr从一个集合移动到另一个集合
Move unique_ptr from set to set
我似乎无法理解这一点,并尝试了中的建议
在集合之间移动`unique_ptr`
如何移动std::unique_ptr<gt;从一个STL容器到另一个?
我有两个包含唯一指针的集合:
std::set<std::unique_ptr<some_type>> s1, s2;
指针当然是唯一的,但some_type的值可能是也可能不是,因此在将s2加入s1之后,s1的大小可能与|s1+s2|相同或大。
看来我应该能够做到这一点:
move(s2.begin(), s2.end(), inserter(s1, s1.end()));
但这失败了,clang++3.8/g++5.4。
这里少了什么?
它不起作用,因为std::set
只允许const
访问其元素。没有办法将某些东西从std::set
中移出。请参阅是否可以将项目从std::集中移出?
在C++14中没有很好的方法可以做到这一点,但在C++17中,有一种merge
方法可用于此目的,它只需重新排列数据结构的内部指针,而不复制或移动任何元素:
s1.merge(s2);
C++14中一个比较合理的变通方法是将std::set<std::unique_ptr<T>>
更改为std::map<T*, std::unique_ptr<T>>
。然后你可以做:
while (!s1.empty()) {
s2[s1.begin()->first] = std::move(s1.begin()->second);
s1.erase(s1.begin());
}
当前您正在将集合成员资格与所有权混为一谈,这就是问题的根源。
解决方案:使用一组原始指针,并将所有权转移到其他地方。
关于设想的
move(s2.begin(), s2.end(), inserter(s1, s1.end()));
在标准库中,move
只是一个荣耀的演员阵容,而不是一个动作例程。命令式名称形式具有误导性。把std::move
想象成as_moveable
。
在C++17中,您可以使用std::set::merge
来执行您想要的操作,如下例所示:
std::set<std::unique_ptr<T>> s1, s2;
...
s1.merge(s2);
实时演示
C++11的变通方法虽然相当昂贵,但有点违背了unique_ptr
的概念,这也需要您的对象是可复制的。将第二个std::set
的对象复制到新的std::unique_ptr
中,您将插入到第一个集合中:
std::set<std::unique_ptr<T>> s1, s2;
...
for(auto &&e : s2) {
s1.insert(std::make_unique<T>(*e));
}
s2.clear();
请注意,在最后,你必须clear
你的第二套,才能从std::unique_ptr
概念的疯狂分离所引起的混乱中恢复过来。
实时演示
- 实现一个在集合上迭代的模板函数
- 如何将一个单词拆分成字母,并将它们放入一个无序的列表/集合中
- 仅从无序集合中删除一个项目
- 如何从一个无序集合中获取一个元素
- 大三实现在一个集合类
- (也许是NP-Hard)求一个集合的子集总数,使得每个子集在与其所有元素相乘时的值都大于X
- 如何在C 中输出集合的最后一个元素
- 一个类用于集合和字典 (map)
- 创建一个抽象类类型的集合,shared_ptr的抽象类向量
- 模板模板集合接受另一个模板参数
- 将“Eigen::VectorXd”的集合合并为一个大的“Eigen::VectorXd”
- Qt:为模板(映射、列表、集合等)构建一个可变迭代器
- 维护多集中数字的排序列表和另一个集合中的累积总和
- C 迭代器到集合的最后一个元素
- 如果对象尚未在集合中,则创建一个对象
- std::set的替代品(可以将元素从一个集合移动到另一个集合)
- 检查当前元素是否是集合的最后一个元素
- 使用shared_ptr<字符串>转换为一个无序集合<字符串>
- 只有Arduino的第一个对象在包含在另一个对象的集合/数组中时会丢失其数据属性值
- 如果您在c++中更新一个集合的成员,该集合会自动更改顺序吗