Unordered_map 与地图
Posted
技术标签:
【中文标题】Unordered_map 与地图【英文标题】:Unordered map vs map 【发布时间】:2020-12-06 10:13:46 【问题描述】:有谁知道为什么Dict
类无效但Dict2
没问题?
#include <string>
#include <unordered_map>
#include <map>
#include <variant>
class Dict
public:
Dict()
private:
std::unordered_map<std::string, std::variant<Dict, std::string>> data;
;
class Dict2
public:
Dict2()
private:
std::map<std::string, std::variant<Dict2, std::string>> data;
;
int main()
Dict d;
Dict2 d2;
return 0;
我得到一个错误
‘value’ is not a member of ‘std::is_trivially_move_constructible<Dict>’
.
我查找了普通移动和复制构造的概念,据我所知,应该定义或删除移动构造函数。
我猜这是因为使用std::unordered_map
和std::variant
并且编译器不知道应该如何移动对象。但我不确定我是否理解正确。
【问题讨论】:
【参考方案1】:我相信这两种情况下的行为都是未定义的。 Dict2
只是偶然执行编译; “似乎有效”是未定义行为的一种可能表现形式。
[res.on.functions]/1 在某些情况下(替换函数、处理函数、对用于实例化标准库模板组件的类型的操作),C++ 标准库依赖于由一个 C++ 程序。如果这些组件不符合其要求,则本国际标准不要求 实施。
[res.on.functions]/2 特别是,在以下情况下效果未定义: ... (2.5) — 如果在实例化模板组件时将不完整类型 (6.9) 用作模板参数,除非该组件特别允许。
Dict
和 Dict2
是不完整的类型,直到它们的定义的右大括号。 std::variant
不允许使用不完整的类型进行实例化。
【讨论】:
感谢您的回答。那么如何建议解决这个问题呢?我还使用std::map
进行了进一步测试,它的行为符合我的预期。我可以创建一个指向std::string
的key1
和一个指向模仿链表行为的同一类的对象的key2
。但是我不能用std::unordered_map
来做这件事,因为它不能编译。
好吧,作为一种快速解决方法,您可以在堆上分配嵌套的Dict
,如std::variant<std::unique_ptr<Dict>, std::string>
。 std::unique_ptr
明确允许不完整类型作为参数。以上是关于Unordered_map 与地图的主要内容,如果未能解决你的问题,请参考以下文章
unordered_map 哈希函数 / 如何防止 unordered_map 被卡
c++ unordered_map 碰撞处理,调整大小和重新散列