问题
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?
回答1:
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)
回答2:
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.
来源:https://stackoverflow.com/questions/13890747/hash-function-for-user-defined-class-how-to-make-friends