std::unordered_set<Foo> 作为 Foo 类的成员

std::unordered_set<Foo> as member of class Foo

本文关键字:Foo 作为 成员 gt lt unordered set std      更新时间:2023-10-16

我正在编写一个类,该类有一个自己类型的unsodered_set作为成员。因此,我需要为hash<Foo>编写一个专门化。这种专门化需要在Foo声明之后进行定义。但在我看来,在定义成员unordered_set<Foo>之前,我似乎已经需要对hash<Foo>进行专门化。至少它没有编译并且在那里失败了。我尝试了哈希模板的前向声明,但也无法使其正常工作。

相关代码片段为:

class Foo {
public:
    int i;
    std::unordered_set<Foo> dummy;
    Peer(std::unordered_set<Foo>);
};
namespace std {
    template<> struct hash<Foo>
    {
        size_t operator()(const Foo& f) const
        {
            return hash<int>()(f.i);
        }
    };
}

提前感谢

Foo不能有std::unordered_set<Foo>类型的成员变量。

不能实例化类型不完整的标准库容器。基本上,除了几个与此无关的例外,类类型直到}终止其定义时才算完整。

您要么需要在容器中存储一些其他类型(可能是std::unique_ptr<Foo>),要么使用一个容器库,该库提供了可实例化的不完整类型的容器(例如,Boost有这样一个容器图书馆)。

您可以将声明移动一点以使其编译:

class Foo;
namespace std {
  template<> struct hash<Foo> {
    size_t operator()(const Foo& f) const;
  };
}
class Foo {
public:
  int i;
  std::unordered_set<Foo> dummy;
  Foo(std::unordered_set<Foo>);
};
namespace std {
  size_t hash<Foo>::operator()(const Foo& f) const {
    return hash<int>()(f.i);
  }
}

然而,正如James所说,dummy的声明是未定义的行为。

您还需要进行平等比较;最容易将CCD_ 9添加到CCD_。

我还建议Foo的构造函数通过const引用来接受参数。