2011-10-01 19 views
12

मैं एक सी ++ टेम्पलेट विशेषज्ञता को परिभाषित करना चाहता हूं जो किसी दिए गए बेस क्लास के सभी उप-वर्गों पर लागू होता है। क्या यह संभव है?सभी उप-वर्गों के लिए टेम्पलेट विशेषज्ञता

विशेष रूप से, मैं इसे एसटीएल के हैश <> के लिए करना चाहता हूं। हैश <> एक खाली parametrized टेम्पलेट के रूप में परिभाषित किया गया है, और विशेष प्रकार के लिए विशेषज्ञता के एक परिवार:

template<class _Key> 
    struct hash { }; 

template<> 
    struct hash<char> 
    { 
    size_t 
    operator()(char __x) const 
    { return __x; } 
    }; 

template<> 
    struct hash<int> 
    { 
    size_t 
    operator()(int __x) const 
    { return __x; } 
    }; 
... 

मैं कुछ इस तरह परिभाषित करना चाहते हैं:

template<class Base> 
    struct hash { 
    size_t operator()(const Base& b) const { 
     return b.my_hash(); 
    } 
    }; 

class Sub : public Base { 
    public: 
    size_t my_hash() const { ... } 
}; 

और की तरह उपयोग करने में सक्षम हो इस:

hash_multiset<Sub> set_of_sub; 
set_of_sub.insert(sub); 

हालांकि, एसटीएल से सामान्य से एक के साथ मेरी हैश टेम्पलेट विरोध करता है। क्या किसी टेम्पलेट विशेषज्ञता को परिभाषित करने के लिए कोई तरीका है (शायद लक्षणों का उपयोग करना) जो किसी दिए गए बेस क्लास के सभी उप-वर्गों पर लागू होता है (एसटीएल परिभाषाओं को संशोधित किए बिना)?

नोट मुझे पता है कि मैं कुछ अतिरिक्त टेम्प्लेट पैरामीटर जब भी इस हैश विशेषज्ञता की जरूरत है साथ ऐसा कर सकते हैं, लेकिन मैं चाहता हूँ इस से बचने के लिए यदि संभव हो तो:

template<> 
    struct hash<Base> { 
    size_t operator()(const Base& b) const { 
     return b.my_hash(); 
    } 
    }; 

.... 

// similar specialization of equal_to is needed here... I'm glossing over that... 
hash_multiset<Sub, hash<Base>, equal_to<Base> > set_of_sub; 
set_of_sub.insert(sub); 
+0

यदि यह विरोधाभासी क्यों नामस्थान का उपयोग नहीं करता है? – Arunmu

+1

http://stackoverflow.com/questions/1032973/how-to-partially-specialize-a-class-template-for-all-derived-types –

+0

का एक संभावित डुप्लिकेट ... जहां समाधान सभी का नाम है व्युत्पन्न कक्षाएं इसी तरह से, जो काफी संतोषजनक नहीं है। – jpalecek

उत्तर

1

समाधान SFINAE उपयोग करने के लिए तय करने के लिए है वर्ग विरासत संरचना के आधार पर आपकी विशेषज्ञता को अनुमति देना है या नहीं। बूस्ट में आप इसे लागू करने के लिए enable_if और is_base_of का उपयोग कर सकते हैं।

+0

मुझे डर है कि आप इस विशेष मामले में 'enable_if' का उपयोग नहीं कर सकते हैं। – jpalecek

+0

jpalecek: क्यों नहीं? बीटीडब्लू, अगर बूस्ट यहां जवाब है, तो यह मेरी मदद नहीं कर सकता है, क्योंकि मेरी कार्यस्थल उन पुस्तकालयों को प्रतिबंधित करती है जिनका हम उपयोग कर सकते हैं, और बढ़ावा दें :: enable_if निर्धारित सबसेट का हिस्सा नहीं है। –

+0

फिर आपको अपना खुद का रोल करना पड़ सकता है, लेकिन आपको कुछ ऐसा करने में सक्षम होना चाहिए जो आप SFINAE का उपयोग करके करना चाहते हैं। – KayEss

0

यह सबसे अच्छा था मैं कर सकता:

template<> 
    struct hash<Sub> : hash<Base> { 
    }; 

मुझे लगता है कि मैं operator() आभासी बनाने के लिए नहीं था एक छोटे से चिंतित हूँ, हालांकि ।

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