使用哈希模板特化相互引用的两个类

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&lt;B&gt;': an undefined class is not allowed as an argument to compiler intrinsic type trait '__is_empty'

如果我不转发声明哈希模板特化,它会告诉我在它已经使用后我不能声明它。

我还尝试将哈希模板专业化的定义移动到我现在要声明它的位置,这也给了我一个错误。

我该怎么做才能使它编译并按照我在此处列出的方式运行?

我唯一能想到的就是重新定义 B 以存储 std::unique_ptr&lt;A&gt; 之类的东西,转发声明 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&lt;B, int&gt;是完整的,你需要A是可定义的,但你需要A已经定义和完成才能使B完成:一个循环.没有一致的方法可以使这项工作按原样进行。将指针放在某处 我没有看到任何实际阻止std::hash&lt;B&gt; 特化的东西,连同它的() 运算符,要在A 的定义之前定义,然后实现()其他地方的运营商。 【参考方案1】:

对于class B 的前向声明,编译器 的名称为class B,但没有任何关于它的属性(size)。

这样你就不能使用它,定义std::unordered_map&lt;B, int&gt; map;,但是你可以使用指针(*)或引用(&)使undefinedstd::unordered_map

static std::unordered_map<B, int> &map;

std::unordered_map<B, int> *map;

【讨论】:

我最终选择了std::unique_ptr&lt;std::unordered_map&lt;B, int&gt;&gt;,但这遵循了这个概念。

以上是关于使用哈希模板特化相互引用的两个类的主要内容,如果未能解决你的问题,请参考以下文章

类型和函数的模板类特化添加

使用另一个模板的模板特化

STL hash function的模板特化

5月4日:unordermap/set,哈希以及哈希常用的拉链法,开放地址法,以及模板的特化相关应用

C++模板编程中只特化模板类的一个成员函数(花样特化一个成员函数)

模板的全特化与偏特化