Hash function for user defined class. How to make

2019-01-26 05:58发布

I have a class C, which has a string* ps private data member.
Now, I'd like to have an unordered_map<C, int> for which I need a custom hash function.

According to the c++ reference, I can do that like

namespace std {
  template<>
  class hash<C> {
  public:
    size_t operator()(const C &c) const
    {
      return std::hash<std::string>()(*c.ps);
    }
  };
}

The problem is that I can't seem to make operator() and C friends so that I could access ps.

I have tried this:

class C;
template<>
class std::hash<C>;
class C{
  //...
  friend std::hash<C>::operator ()(const C&) const; // error: Incomplete type 
};
// define hash<C> here.

but it says that Incomplete type ... in nested name specifier ...

I can't turn around the definitions either, because if class C is defined later, the hash<C> has no way to know about ps.

What am I doing wrong here? How can this situation be fixed without making ps public?

2条回答
等我变得足够好
2楼-- · 2019-01-26 06:06

Try this:

class C;
namespace std {
  template<>
  struct hash<C> {
  public:
    size_t operator()(const C &c) const; // don't define yet
  };
}
class C{
  //...
  friend std::hash<C>::operator ()(const C&) const;
};
namespace std {
  template<>
  size_t hash<C>::operator()(const C &c) const {
    return std::hash<std::string>()(*c.ps);
  }
}

Or this:

class C;
template<>
struct std::hash<C>;
class C{
  friend struct std::hash<C>; // friend the class, not the member function
};

(I haven't compiled so there might be a syntax error)

查看更多
叼着烟拽天下
3楼-- · 2019-01-26 06:16

I'd suggest to add method like following

class C
{
....
public:  const string* get_ps() const { return ps; }
....
};

and use it in the your hash specialization.

查看更多
登录 后发表回答