यह असंभव है आंशिक रूप से फ़ंक्शन टेम्पलेट का विशेषज्ञ है, और इसलिए उपयोगकर्ता द्वारा परिभाषित टेम्पलेटेड क्लास के लिए, std::hash
विशेषज्ञ होने का कोई तरीका नहीं होगा यदि यह एक फ़ंक्शन था। (आप केवल std
नेमस्पेस से टेम्पलेट्स का विशेषज्ञ कर सकते हैं, लेकिन ओवरलोड नहीं कर सकते हैं, इसलिए आपके टेम्पलेटेड क्लास के उपयोगकर्ता std::unordered_map<MyClass<whatever>, MyOtherClass>
नहीं बना सकते हैं, उन्हें std::unordered_map<MyClass<whatever>, MyOtherClass, ???>
चुनने के लिए मजबूर किया जाएगा)। तो मज़ेदार यहां समाधान है।
namespace std
{
template<typename T>
struct hash<MyVector<T>>
{
size_t operator()(const MyVector<T>& v)
{
//return hash from here
}
};
}
मानक पुस्तकालय के लिए वैकल्पिक तरीका कुछ SFINAE टेम्पलेट चाल का उपयोग किया जाएगा डिफ़ॉल्ट के रूप में सदस्य .hash()
, और मानक हैश अन्य मामले अगर चयन करने के लिए, लेकिन ज्यादातर मामलों में आप विशेष रूप से यदि का उपयोग कर इंटरफेस पुनः स्थापित नहीं कर सकते हैं (तीसरे पक्ष के कोड)
अन्य वैकल्पिक std::swap
जैसा होगा (ADL साथ चाल) करता है:
//somewhere in std::unordered_map
using std::hash;
size_t h = hash(key);
मेरे अनुभव में, ADL मुश्किल है और हर कोई कोने मामलों के बारे में याद करते हैं। इसके अलावा, यहां फ़ैक्टरों का लाभ यह तथ्य है कि आप उन्हें टेम्पलेट पैरामीटर के रूप में उपयोग कर सकते हैं, ताकि आप टेम्पलेट के लिए बस एक और मज़ेदार प्लग-इन कर सकें (जैसे std::unordered_map<A, B, specialized_hash<A>>
) यदि आपको लगता है कि डिफ़ॉल्ट आपके मामले के लिए गलत है।
टिप्पणियों से:
लेकिन आप std :: स्वैप बारे में कुछ और विस्तार से बता सकता है? यह अभी भी सी ++ 11 में है और इसमें उपयोगकर्ता द्वारा परिभाषित प्रकारों में कोई समस्या नहीं है, है ना? क्यों इसे लगातार बनाने के बजाय एसटीएल में कई अलग-अलग अवधारणाएं रखें?
std::hash
में:
- यह संभव है कि, उदाहरण के लिए
std::swap
और std::hash
के बीच एक छोटा सा फर्क है std::string
कक्षा लेखक द्वारा परिभाषित हैश आपके मामले के लिए पर्याप्त नहीं होगा, यानी, यह बहुत सामान्य है, और आप अपने हैश मैप में गारंटी दे सकते हैं कि आप केवल एक ही प्रकार के तार डाल देंगे, ताकि आप हैश फ़ंक्शन प्रदान कर सकें जो तेज़ है या/और कम टकराव होने।
- यह है:
- वहाँ विभिन्न प्रयोजनों के लिए हैश के कई तरह तो genericity अब तक कम यहां महत्वपूर्ण है
- ज्यादातर मामलों में यह संभव है आप एक बेहतर हैश
std::swap
में बनाने के लिए कर रहे हैं संभावना नहीं है कि आप अपना स्वयं का स्वैप फ़ंक्शन चाहते हैं, लेकिन आप अभी भी इस वर्ग के लिए एक विशिष्ट का उपयोग करना चाहेंगे, न कि सामान्य std::swap
जो कॉपी कन्स्ट्रक्टर कहता है।
ज्यादातर मामलों में एक स्वैप फ़ंक्शन बनाने के लिए आपके लिए भी संभव नहीं है, क्योंकि इसे कक्षा आंतरिक के ज्ञान की आवश्यकता होती है (उदाहरण के लिए, std::vector
को निजी क्षेत्र के रूप में छिपे पॉइंटर के साथ गतिशील सरणी के रूप में कार्यान्वित किया जा सकता है, इसलिए आप नहीं होंगे उन्हें एक्सेस करने में सक्षम, अकेले उन्हें स्वैप नहीं किया गया है, और यहां तक कि इस तथ्य को लागू करने वाला तथ्य भी गारंटी नहीं है)
केवल एक स्वैप (या होना चाहिए) है।
वास्तव में, वहाँ std::swap
साथ एक समस्या है: मानक कंटेनर swap
सदस्य समारोह, std::swap
विशेष किया जा सकता है (लेकिन केवल गैर टेम्प्लेटेड वर्ग के लिए) प्रदान करते हैं और स्वैप एक नि: शुल्क समारोह है कि ADL के साथ पाया है के रूप में परिभाषित किया जा सकता है। आपको अपना स्वैप कैसे प्रदान करना चाहिए? आईएमओ जो उलझन में है, तथ्य यह नहीं कि std::swap
कार्य है और std::hash
एक मजेदार है।
एसटीएल असंगत क्यों है? मैं केवल यहां अनुमान लगा सकता हूं, लेकिन मुख्य कारण एसटीएल असंगत क्यों है (ए) बाकवर्ड संगतता और (बी) सी ++ भी काफी असंगत है।
@RiaD दाएं, धन्यवाद। अचानक, यह और भी अजीब लगता है। –