使用哈希模板特化相互引用的两个类
Posted
技术标签:
【中文标题】使用哈希模板特化相互引用的两个类【英文标题】:Two classes referencing each other with hash template specialization 【发布时间】:2020-06-25 23:45:13 【问题描述】:我有两个类,A 和 B,它们都需要能够相互引用,如下所示。
// A.h
class B; // Forward declare B
template<>
struct std::hash<B>; // Forward declare hash template specialization for B
class A
std::unordered_map<B, int> map;
;
// B.h
#include "A.h"
class B
A object;
template<>
struct std::hash<B>
size_t operator()(__in const B& toHash) const;
在当前状态下,它告诉我error C2139: 'std::hash<B>': an undefined class is not allowed as an argument to compiler intrinsic type trait '__is_empty'
如果我不转发声明哈希模板特化,它会告诉我在它已经使用后我不能声明它。
我还尝试将哈希模板专业化的定义移动到我现在要声明它的位置,这也给了我一个错误。
我该怎么做才能使它编译并按照我在此处列出的方式运行?
我唯一能想到的就是重新定义 B 以存储 std::unique_ptr<A>
之类的东西,转发声明 A 而不是 B,并让 A 导入 B.h 而不是 B 导入 A.h。但这感觉像是一个奇怪的解决方案,并没有真正解决这样的依赖问题。我错过了什么吗?
【问题讨论】:
这是一个没有实际意义的问题。容器中不允许B
不完整 (SO post),并且在我尝试的任何实现中都不起作用。
这是这里问题的一部分。据我所知,哈希具体是原因,但我可能错了。我怎样才能最好地解决这种循环出现的依赖关系?
哈希不是原因。我不断看到的错误在于 unordered_map 本身,当它尝试实例化其节点类型时。
另一种选择是将unordered_map
放在指针后面,如I suggest a couple iterations of this question back. 不,std::hash
不是问题。 C++标准说B
必须是完整的std::unordered_map<B, int>
是完整的,你需要A
是可定义的,但你需要A
已经定义和完成才能使B
完成:一个循环.没有一致的方法可以使这项工作按原样进行。将指针放在某处。
我没有看到任何实际阻止std::hash<B>
特化的东西,连同它的()
运算符,要在A
的定义之前定义,然后实现()
其他地方的运营商。
【参考方案1】:
对于class B
的前向声明,编译器 的名称为class B
,但没有任何关于它的属性(size)。
这样你就不能使用它,定义std::unordered_map<B, int> map;
,但是你可以使用指针(*)或引用(&)使undefined
std::unordered_map
static std::unordered_map<B, int> ↦
或
std::unordered_map<B, int> *map;
【讨论】:
我最终选择了std::unique_ptr<std::unordered_map<B, int>>
,但这遵循了这个概念。以上是关于使用哈希模板特化相互引用的两个类的主要内容,如果未能解决你的问题,请参考以下文章
5月4日:unordermap/set,哈希以及哈希常用的拉链法,开放地址法,以及模板的特化相关应用