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

时间:2012-01-08 22:22:47

标签: c++ stl hash unordered-set explicit-specialization

我正在编写一个具有自己类型的unordered_set作为成员的类。 因此,我需要为hash<Foo>编写专门化。在声明Foo之后需要定义此特化。但在我看来,在定义成员hash<Foo>之前,我似乎已经需要unordered_set<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);
        }
    };
}

提前致谢

2 个答案:

答案 0 :(得分:8)

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

您无法实例化具有不完整类型的标准库容器。基本上,这里有几个不相关的例外,在}终止其定义之前,类类型是不完整的。

您需要在容器中存储其他类型(可能是std::unique_ptr<Foo>),或者使用容器库来提供可实例化的不完整类型的容器(例如,Boost具有这样的容器库)。 / p>

答案 1 :(得分:1)

您可以稍微移动声明以使其编译:

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);
  }
}

正如詹姆斯所说,dummy的声明是未定义的行为。

您还需要进行相等比较;最简单的方法是将operator==添加到Foo

我还建议让Foo的构造函数通过const-reference获取参数。