2012-04-13 10 views
7

को देखते हुए इस टेम्पलेट जोड़ने के लिए वैकल्पिक करने के लिए enable_if का उपयोग करना:एक struct सदस्य

template <class A> 
struct Something { 
    ... // members common to all template instantiations for all A types 
    SpecialType member; // but not this - I want this to be conditional... 
} 

... मैं "enable_if" का उपयोग करने SpecialType सदस्य सशर्त मौजूद करना चाहते हैं; यही वह समय है जब टेम्पलेट को ए = स्पेशलकेस 1 या स्पेशलकेस 2 प्रकारों के साथ तुरंत चालू किया जाता है। अन्य सभी मामलों में, मैं चाहता हूं कि स्पेशलटाइप सदस्य गुम हो जाए।

यदि आप सोच रहे हैं कि यह अनुकूलन के बारे में है - यानी संरचना में बेकार पेलोड नहीं ले रहा है। मैं टेम्पलेट मेटाप्रोग्रामिंग में नौसिखिया हूं, लेकिन मुझे समझ में आता है कि मुझे किसी भी तरह "enable_if" और दो "is_same" की ज़रूरत है - यह सुनिश्चित नहीं है कि कैसे ...

संपादित करें: जेनेरिक सी ++ (यानी बूस्ट-विनिर्देशों के बिना) एक प्लस होगा।

उत्तर

5

अच्छी तरह से: बेस क्लास का उपयोग करें।

struct Empty {}; 

struct SpecialTypeCnt { SpecialType member; }; 

template <typename A> 
struct Something: if_< /* cond */ , SpecialTypeCnt, Empty>::type { 
}; 

कहाँ if_ के रूप में परिभाषित किया गया है:

template <typename, typename, typename E> struct if_ { typedef E type; }; 

template <typename T, typename E> 
struct if_<std::true_type, T, E> { typedef T type; }; 

(तुम भी एक बूलियन पर विशेषज्ञ कर सकते हैं)

अब जाहिर है, आप ठीक ढंग से अपनी हालत को व्यक्त करने की जरूरत है।


ऐसा कहकर, आपको शायद struct का उपयोग नहीं करना चाहिए। इसके बजाय आपको class का उपयोग करना चाहिए जो member पर लागू होने वाले संचालन प्रदान करता है। फिर आप एक class Null को डिफ़ॉल्ट व्यवहार और class SomeType के साथ member के विशिष्ट व्यवहार के साथ प्रदान करते हैं।

अन्यथा आप member को संशोधित करने के लिए "शायद" हर जगह की स्थिति को फिर से लिखेंगे, और यह कष्टप्रद असली त्वरित हो जाता है।

+2

पर सुझाया है, 'if_' को आमतौर पर 'std :: conditional' कहा जाता है। –

+0

@ केरेकस्क: आह धन्यवाद, मैं कुछ हद तक पुराना टाइमर हूं, मुझे डर है। बूस्ट एमपीएल में यह 'if_' था :) मैंने अभी तक सी ++ 11 नई पुस्तकालयों में बहुत कुछ खोला नहीं है:/ –

5

आपको इसके लिए enable_if की आवश्यकता नहीं है। विशेष मामलों के लिए अपनी संरचना को विशेषज्ञ बनाएं और बाकी के लिए डिफ़ॉल्ट कार्यान्वयन छोड़ दें:

template <class A> 
struct Something 
{ 
    // your default implementation 
}; 

template <> 
struct Something<SpecialCase1> 
{ 
    // your SpecialCase1 implementation 
}; 

template <> 
struct Something<SpecialCase2> 
{ 
    // your SpecialCase2 implementation 
}; 
+0

यही होगा कारण फिर से सभी सामान्य क्षेत्रों और सदस्य कार्यों की याचिका - मैं इस से बचना चाहता हूं (डीआरवाई)। – ttsiodras

+0

@ttsiodras - रचना या विरासत का उपयोग करें और जो मैंने किसी सदस्य या बेस क्लास – bobah

2

आदेश आम सदस्यों नकल करने नहीं में:

परिभाषित BaseSomething वर्ग:

template <class A> 
     struct BaseSomething { 
      ... // members common to all template instantiations for all A types 
       }; 

परिभाषित SpecialSomething वर्ग:

template <class A> 
      struct SpecialSomething { 
       SpecialType member; 
       ...//SpetialType related functionality 
        }; 

परिभाषित कुछ वर्ग:

template <class A> 
      struct Something :public BaseSomething<A>{ 

        }; 



    template<> 
    struct Something<SpecialCase1>:public BaseSomething<A>{ 
        SpecialSomething<SpecialCase1> special; 
         }; 


template<> 
struct Something<SpecialCase2>:public BaseSomething<A>{ 
       SpecialSomething<SpecialCase2> special; 
        }; 
+0

यह मेरी सबसे जरूरी चीज है जो मुझे चाहिए - लेकिन निश्चित रूप से यह एक पंक्ति से अधिक वर्बोज़ है "enable_if" ... – ttsiodras

+2

यदि वर्बोज़ आपके लिए काम नहीं करता है तो आपको कम से कम C++ भाषा का उपयोग करने की अपनी पसंद पर एक कड़ी नजर डालना चाहिए।यह कई बार बहुत verbose हो सकता है। –

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