मैं सी ++ में एक वर्ग को लागू करने की कोशिश कर रहा हूँ सी में एक वर्ग ++ भीतर hashCode विधि परिभाषित कर सकता हूँ, और मैं प्रत्येक वर्ग चाहते hashCode के अपने स्वयं के कार्यान्वयन (मूल रूप से 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);
}
*/
};
अब, मान लीजिए मैं
int main(){
unoredered_map<CustomClass, int> m;
}
की तरह एक unordered_map में इस का उपयोग करना चाहते मैं दो opti है ऑन,
i) टेम्पलेट विशेषज्ञता के साथ एसटीडी नाम स्थान में hashCode सम्मिलित करें
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);
}
};
}
या
ii।), जबकि unordered_map
(या unordered_set
) हर बार बनाने के दौरान यह instantiating, यानी इस समारोह को निर्दिष्ट करें
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
को तत्काल करते समय, मैंने यह संरचना प्रदान की है।
int main(){
unoredered_map<CustomClass, int, HashSpecialer> m;
}
मुझे लगता है दोनों तरीकों (i) एसटीडी नाम स्थान को प्रदूषित करता है और (ii) यह मुश्किल बना देता है HashSpecializer हर बार जब मैं एक unordered_map
का दृष्टांत प्रदान करने के लिए याद करके उपयोग करने के लिए भ्रमित करने के लिए यह संभव है जैसा कि मैंने
से ऊपर कोड स्निपेट में टिप्पणी अनुभाग में वर्णित है, जैसा कि मैंने कक्षा में हैशकोड() विधि को ओवरराइड कर दिया है और हम इस कार्यक्षमता को प्राप्त कर सकते हैं। एक बार जब मैं हैशकोड() विधि को ओवरराइड करता हूं, तो मुझे इसके बारे में चिंता करने की आवश्यकता नहीं है।
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;
}
}
मैं ऐसा कुछ ढूंढ रहा हूं क्योंकि यह बहुत आसान साबित होता है।
'std :: हैश' की विशेषज्ञता उचित खेल है। Http://en.cppreference.com/w/cpp/utility/hash/operator() पर नमूना कोड देखें। –
@RSahu Thats जो मैं अब उपयोग करता हूं। मुझे यह पसंद क्यों नहीं है, इसका एक कारण यह है कि मुझे यकीन नहीं है कि अगर मैं अपने कस्टम क्लास को अलग-अलग फ़ील्ड के साथ एक से अधिक नामस्थान में परिभाषित करता हूं तो मैं स्थिति को कैसे संभाल सकता हूं। यहां तक कि अगर मैं इससे दूर हो सकता हूं, तो यह कोड को पढ़ने में निश्चित रूप से भ्रमित है। मैं अभी भी इस परिदृश्य को संभालने के जावा के तरीके को पसंद करता हूं। – Anoop