在C++中,如何在头文件中声明一个数据结构,而它是在源文件中定义的?

In C++, how to declare a data structure in header file , while it is defined in source file?

假设我想使用 typedef 在源文件中定义一个新的集合 MyTypeSet,其中包含自定义的散列和比较器函数。我想隐藏源文件中的所有实现细节。

typedef std::unordered_set<MyType, MyTypeHash, MyTypeKeyEqual>
MyTypeSet;

然后我想在头文件中声明MyTypeSet,供其他模块使用。但我不想公开 MyTypeHash 和 MyTypeKeyEqual

只是想不出正确的语法。

typedef 无法做到这一点。 MyTypeSet 的用户需要能够看到 MyTypeMyTypeHashMyTypeKeyEqual 的完整定义才能知道如何编译 MyTypeSet

有几种方法用于从实现细节中区分模板代码的 public 接口:

  • 将实现细节放在另一个 header ("MyTypeImpl.hpp") 中,它包含在 public header.
  • 将私有实现类型放在名为 detailprivate 或类似名称的命名空间中。
  • 用下划线字符破坏私有名称,如 MyTypeHash_。 (这点可以在MSVC标准库中看到不少)

如果绝对有必要对 MyTypeHashMyTypeKeyEqual 保密,那么可以将 MyTypeSet 声明为 class,它只有最终需要的方法用户。然后 MyTypeSet 可以使用 pImpl idiomstd::unordered_set 作为仅在源文件中可见的成员变量。 MyTypeSet 的所有方法都将通过调用 std::unordered_set 来实现。

这样的 MyTypeSet 不能具有与 std::unordered_set 完全相同的 public 接口,因为 std::unordered_set 将其散列和键类型公开为成员类型。