2012-08-03 13 views
5

मुझे एक बड़ी परियोजना के लिए unordered_set का उपयोग करना है, और यह सुनिश्चित करने के लिए कि मैं इसे सही तरीके से उपयोग कर रहा हूं, मैंने एक छोटा सा उदाहरण करने की कोशिश की।सी ++ में unordered_set के लिए हैश फ़ंक्शन घोषित करना?

#include <iostream> 
#include <unordered_set> 
using namespace std; 

class Foo { 
    private: 
    int x; 
    public: 
    Foo(int in) {x = in;} 
    bool operator==(const Foo& foo) const {return x == foo.x;} 
    size_t hash(const Foo& foo) const {return x;} 
}; 

int main() { 
    Foo f1(3); 
    unordered_set<Foo> s; 
    s.insert(f1); 
    return 0; 
} 

जब मैं संकलन मैं:

/tmp/cc3KFIf4.o: In function `std::__detail::_Hash_code_base<Foo, Foo, std::_Identity<Foo>, std::equal_to<Foo>, std::hash<Foo>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>::_M_hash_code(Foo const&) const': 
hashset.cc:(.text._ZNKSt8__detail15_Hash_code_baseI3FooS1_St9_IdentityIS1_ESt8equal_toIS1_ESt4hashIS1_ENS_18_Mod_range_hashingENS_20_Default_ranged_hashELb0EE12_M_hash_codeERKS1_[std::__detail::_Hash_code_base<Foo, Foo, std::_Identity<Foo>, std::equal_to<Foo>, std::hash<Foo>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>::_M_hash_code(Foo const&) const]+0x19): undefined reference to `std::hash<Foo>::operator()(Foo) const' 
/tmp/cc3KFIf4.o: In function `std::__detail::_Hash_code_base<Foo, Foo, std::_Identity<Foo>, std::equal_to<Foo>, std::hash<Foo>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>::_M_bucket_index(std::__detail::_Hash_node<Foo, false> const*, unsigned int) const': 
hashset.cc:(.text._ZNKSt8__detail15_Hash_code_baseI3FooS1_St9_IdentityIS1_ESt8equal_toIS1_ESt4hashIS1_ENS_18_Mod_range_hashingENS_20_Default_ranged_hashELb0EE15_M_bucket_indexEPKNS_10_Hash_nodeIS1_Lb0EEEj[std::__detail::_Hash_code_base<Foo, Foo, std::_Identity<Foo>, std::equal_to<Foo>, std::hash<Foo>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>::_M_bucket_index(std::__detail::_Hash_node<Foo, false> const*, unsigned int) const]+0x28): undefined reference to `std::hash<Foo>::operator()(Foo) const' 
collect2: ld returned 1 exit status 

ऐसा लगता है कि यह मेरे हैश फंक्शन नहीं देख रहा है, लेकिन मैंने सोचा था कि "हैश" डिफ़ॉल्ट समारोह नाम था। क्या मैंने हैश सही ढंग से परिभाषित किया? या क्या मुझे दूसरी टेम्पलेट तर्क के रूप में एक अलग हैश क्लास को स्पष्ट रूप से घोषित करने की आवश्यकता है?

+1

हैश कार्यक्षमता एक अतिरिक्त टेम्पलेट पैरामीटर के रूप में पारित की जाती है। आपको (अधिमानतः) एक मज़ेदार की आवश्यकता है और 'unordered_set s (FooHasher()); ' – Xeo

उत्तर

8

टिप्पणियों में ज़ीओ के सुझाव के विकल्प के रूप में, आप unordered_set को तत्काल करने से पहले std::hash के लिए एक विशेषज्ञता प्रदान कर सकते हैं।

namespace std { 
    template <> 
    struct hash<Foo> { 
     size_t operator() (const Foo &f) const { return f.hash(f); } 
    }; 
} 

अपने hash विधि के लिए foo पैरामीटर मेरे लिए बाहरी लगता है, लेकिन मैं इंटरफ़ेस आपके द्वारा प्रदान किए विशेषज्ञता को लागू किया।

+0

ठीक है धन्यवाद, यह काम करता है। मैं वास्तव में एक अतिरिक्त पैरामीटर लेने के लिए अपने हैश फ़ंक्शन के लिए नहीं था, जो एक टाइपो है। यह आकार_टी हैश() कॉन्स {रिटर्न एक्स;} एकमात्र चीज़ जो मैं उलझन में हूं, वह क्यों है कि मैं सिर्फ हैश() जैसे ऑपरेटर ==() के साथ नहीं कर सकता? ऑपरेटर के लिए == मुझे कुछ भी अतिरिक्त करने की ज़रूरत नहीं थी। – user1575106

+0

@ user1575106: विभिन्न एपीआई की अलग-अलग आवश्यकताएं होंगी। मानकों के लेखक हर किसी की इच्छा को पूरा नहीं कर सकते हैं, और दिए गए इंटरफेस वर्ग को संशोधित किए बिना विभिन्न हैश एल्गोरिदम को आजमा सकते हैं। – jxh

संबंधित मुद्दे