我们可以在C ++中的类中定义哈希码方法吗 [英] Can we define hashcode method within a class in C++
问题描述
我正在尝试在C ++中实现一个类,并且我希望每个类都具有自己的哈希码实现(基本上是将其用作unordered_map
& unordered_set
中的键)
I am trying to implement a class in C++, and I want each class to have its own implementation of hashcode(basically to use it as a key in unordered_map
& unordered_set
)
例如:
class CustomClass{
int a;
vector<int> b;
string c;
bool operator ==(const CustomClass& o) const{
return ((a == o.a) && (b == o.b) && (c == o.c));
}
/*
Is it possible to define the hashcode function here instead of defining it outside the class.
size_t operator()() const {
// Some custom logic for calculating hash of CustomClass using
// the hash Values of its individual fields
std::size_t h = 0;
for(int& t : b){
h = (h ^ std::hash<int>()(t)) << 1;
}
return (h^(std::hash<int>()(a) << 1))^( std::hash<string>()(c) << 1);
}
*/
};
现在,假设我想在unordered_map中使用它
Now, suppose I want to use this in an unordered_map like
int main(){
unoredered_map<CustomClass, int> m;
}
我有两个选择,
i)使用模板专门化功能将std名称空间中的哈希码注入
i) Inject the hashcode in std namespace with Template specialization
namespace std {
template <> struct hash<CustomClass> {
size_t operator()(const CustomClass& o) const {
// Some custom logic for calculating hash of CustomClass using
// the hash Values of its individual fields
size_t h = 0;
for(int& t : o.b){
h = (h ^ std::hash<int>()(t)) << 1;
}
return (h^(std::hash<int>()(o.a) << 1))^( std::hash<string>()(o.c) << 1);
}
};
}
OR
ii.)在实例化每次创建unordered_map
(或unordered_set
)时都指定此函数,即
ii.) Specify this function while creating the unordered_map
(or unordered_set
) every time while instantiating it, i.e
struct HashSpecialer {
std::size_t operator()(const CustomClass& o) const {
std::size_t h = 0;
for(int& t : o.b){
h = (h ^ std::hash<int>()(t)) << 1;
}
return (h^(std::hash<int>()(o.a) << 1))^( std::hash<string>()(o.c) << 1);
}
};
并在实例化unordered_map
的同时,提供了此结构.
and while instantiating the unordered_map
, I have provide this struct.
int main(){
unoredered_map<CustomClass, int, HashSpecialer> m;
}
我找到了两种方法,这使我感到困惑:(i)污染std名称空间,(ii)每次我实例化unordered_map
I find both the methods, confusing to use (i) Pollutes the std namespace and (ii) makes it hard by remembering to provide the HashSpecializer every time I instantiate an unordered_map
是否有可能在类定义本身中提供哈希码功能,如我在上面代码片段的注释部分所述
注意:在java中,我们可以重写类中的hashCode()方法,并且可以实现此功能.一旦重写了hashCode()方法,以后就不必担心它了.
Is it possible to provide the hashcode function within the class definition itself , as I described in the commented section in the code snippet above
Note : In java , we can override the hashCode() method in the class and we could achieve this functionality. Once I override the hashCode() method, I need not worry about it later.
public class CustomClass {
int a;
List<Integer> b;
String c;
// I Let my IDE generate these methods :D
@Override public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
CustomClass that = (CustomClass) o;
if (a != that.a)
return false;
if (b != null ? !b.equals(that.b) : that.b != null)
return false;
return c != null ? c.equals(that.c) : that.c == null;
}
// This one too :D
@Override public int hashCode()
{
int result = a;
result = 31 * result + (b != null ? b.hashCode() : 0);
result = 31 * result + (c != null ? c.hashCode() : 0);
return result;
}
}
我正在寻找类似的东西,因为事实证明这非常方便.
I am looking for something like this as this proves to be very handy.
推荐答案
我认为,解决您的问题的方法是调整您对美观的C ++程序的理解.
I think the solution to your problem is to adjust your understanding of what is an aesthetically pleasing C++ program.
专门化std::hash
不会污染std名称空间,相反,您应该考虑std::hash
是用于控制unordered_map
如何与您的类一起工作的自定义点.
A specialization of std::hash
doesn't pollute the std namespace, instead you should consider that std::hash
is the customization point for controlling how unordered_map
works with your class.
这种专门化是类接口的一部分(并且可以是该类的朋友),其方式与operator +()
之类的二进制运算符应该是非成员函数完全相同,并且仍然是该类的一部分.界面.
Such a specialization is part of the interface of the class (and can be a friend of the class) in exactly the same way as binary operators like operator +()
should be a non-member functions, and still be part of the interface.
这篇关于我们可以在C ++中的类中定义哈希码方法吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!