如何解决如何使用提取将不可复制的元素从std :: set移动到std :: map?
请考虑以下内容:
const getAll = async () => {
try {
const result: any = {};
const keys = await AsyncStorage.getAllKeys();
for (const key of keys) {
const val = await AsyncStorage.getItem(key);
result[key] = val;
}
return result;
} catch (error) {
alert(error);
}
};
我使用#include <set>
#include <map>
struct MyClass
{
MyClass(int i);
MyClass(MyClass const&) = delete;
~MyClass();
bool operator<(const MyClass& r) const { return v < r.v; }
int v;
};
void map_set_move_test()
{
std::set<MyClass> s1,s2;
std::map<int,MyClass> m1;
s1.emplace(123);
s2.insert(std::move(s1.extract(s1.begin())));
// This fails
m1.insert(std::move(std::make_pair(1,std::move(s2.extract(s2.begin()).value()))));
}
成功将元素从std::set::extract
移动到另一个std::set
,如下所示:
std::set
但是编译器不允许通过以下方式将元素移动到s2.insert(std::move(s1.extract(s1.begin())));
:
std::map
任何帮助将不胜感激。 Link to compiler explorer。
解决方法
这是一个有问题的示例,因为MyClass不仅是不可复制的,而且还隐含地不可移动-这可能不是您的意思。 (我认为MyClass由于您明确删除了复制构造函数而变得不动;请参阅this answer。)
如果您确实将MyClass
设为可移动,则如下所示:
class MyClass : NonCopyable
{
public:
MyClass(int i) : v(i) {
std::cout << "constructor" << std::endl;
}
MyClass(MyClass&& other) : v(other.v) {
std::cout << "move constructor" << std::endl;
}
~MyClass() {
std::cout << "destructor" << std::endl;
}
bool operator<(const MyClass& r) const {
return v < r.v;
}
int v;
};
说的话,一切似乎都进展顺利。
m1.emplace(
1,std::move(
s2.extract(s2.begin()).value()
)
);
您可以在GodBolt上看到它。
PS-正如@DavisHerring所建议的那样,如果您不想覆盖现有值,则可能要使用try_emplace()
方法。
extract
的点和insert
的相应重载是在没有内存分配的情况下操纵基于节点的容器。 (一种有趣的操作是更改std::map
键。)由于节点是不同类型( viz。,一个有键而另一个没有键),因此在这里不起作用。您只需将其与常规 insert
(或更符合人体工程学的try_emplace
)一起使用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。