C++ 重写<T> T 派生类的哈希

C++ Overriding hash<T> for derived classes of T

本文关键字:哈希 派生 gt 重写 C++ lt      更新时间:2023-10-16

几个问题:

  1. 下面的代码没有编译(请参阅下面的注释)
  2. 如果我想让Bar和Baz返回id()作为它们的哈希值,我是否也必须重写它们的哈希函数
#include <functional>
class Foo
{
public:
  Foo(short id);
  short id() const;
private:
  const short id_;
};
class Bar : public Foo {};
class Baz : public Foo {};
Foo::Foo(short id) :
id_(id)
{}
short Foo::id() const
{
  return id_;
}
namespace std
{
  template <> struct hash<Foo> //hash is not a class template
  { //explicit specialization of non-template std::hash
    size_t operator()(const Foo& foo) const
    {
      return hash<short>()(foo.id()); //std::hash is not a template
    }
  };
}

问题是const引用正在传递给hash::operator(),但Foo::id()未声明为const。这将阻止您在Foo的任何const实例上调用id()。要解决此问题,只需像一样声明函数const

class Foo
{
public:
    short id() const;
};

如果定义std::hash的实例并传递其中一个派生类作为模板参数,则需要为每个派生类提供专门化。如果您只是将派生类的实例传递给std::hash<Foo>,则不需要为它们提供专门化。

此外,请确保您使用的是C++11编译器(必要时启用C++11模式),并在注释中包含Kerrek提到的<functional>标头。