2012-10-21 4 views
5

के लिए विकल्प/शायद कक्षा मैं सी ++ में स्काला जैसी विकल्प/हास्केल जैसी कक्षा को लागू करना चाहता हूं। दक्षता कारणों से, मैं गतिशील रूप से आवंटित स्मृति का उपयोग नहीं करना चाहता, न ही मैं बहुरूपता का उपयोग करना चाहता हूं। इसके अलावा, मैं नहीं चाहता कि एम्बेडेड प्रकार का कोई ऑब्जेक्ट बनाया जाए, यदि विकल्प कोई नहीं है।सी ++

क्या कोई मुझे बता सकता है कि निम्नलिखित दृष्टिकोण समस्याएं पैदा कर सकता है या नहीं? मुझे अपने विकल्प वर्ग के भीतर एम्बेडेड ऑब्जेक्ट के लिए स्थैतिक रूप से स्मृति आवंटित करना है, लेकिन मैं एम्बेडेड प्रकार के सदस्य फ़ील्ड को परिभाषित नहीं कर सकता, क्योंकि यह विकल्प ऑब्जेक्ट के निर्माण पर प्रारंभ किया जाएगा, भले ही विकल्प कोई नहीं है।

template <typename T> 
class Option { 
private: 
    uint8_t _storage [sizeof (T)]; 
    T * _embedded; 
public: 
    Option() : _embedded (nullptr) { 
    } 

    Option (const T & obj) : _embedded (new (_storage) T (obj)) { 
    } 

    Option (const Option<T> & other) 
    : _embedded (
     other->_embedded ? new (_storage) T (other->_embedded) : nullptr 
    ) { 
    } 

    // ... 

    ~Option() { 
     if (_embedded) _embedded->~T(); 
    } 
}; 
+2

आप जांच सकते हैं कि कैसे [बूस्ट.ऑप्शनल] (http://www.boost.org/doc/libs/1_51_0/libs/optional/doc/html/index.html) लागू किया गया है। – kennytm

+0

संकेत के लिए धन्यवाद। मुझे पता होना चाहिए कि बूस्ट में यह है। – JohnB

+1

वास्तव में, यह वास्तव में एक चालाक प्रतिनिधित्व है। आपको ** असाइनमेंट ** से भी निपटने की आवश्यकता होगी, लेकिन अन्यथा मुझे वास्तव में केवल एक बूलियन की बजाय पॉइंटर को संग्रहीत करने का विचार पसंद है। निश्चित रूप से चीजों को बाद में आसान बनाता है। –

उत्तर

3

मुझे नहीं लगता कि कि सरणी उसी तरह वस्तु वर्ग की आवश्यकता हो सकती गठबंधन किया जाना आवश्यक है। प्रैक्टिस में मैं किसी भी समस्या की अपेक्षा नहीं करता जब तक कि इस प्रकार के मज़ेदार संरेखण की आवश्यकता न हो।

सी ++ 2011 के साथ आप वास्तविक प्रतिनिधित्व को पकड़ने के लिए union का उपयोग कर सकते हैं, हालांकि आपको अभी भी ऑब्जेक्ट के जीवन-काल को प्रबंधित करने की आवश्यकता होगी। मानक के अगले संशोधन में एक समान प्रकार जोड़ने के लिए boost::optional<T> और proposal है।

+0

बफर के सही संरेखण के लिए आप शायद boost :: aligned_storage का उपयोग कर सकते हैं। – mauve

+0

प्लेसमेंट नए से गठबंधन स्मृति को वापस नहीं करना इस प्रश्न के उत्तर के अनुसार यूबी है: http://stackoverflow.com/questions/11781724/do-i-really-have-to-worry-about-alignment-when-using-placement -न्यू-ऑपरेटर – PiotrNycz

+0

वास्तव में, सी ++ 11 में मैं 'std :: aligned_storage' का उपयोग करने की अपेक्षा करता हूं। यह विशेष रूप से एक सटीक आकार * और संरेखण * के कच्चे भंडारण का अनुरोध करने के लिए बनाया गया था। –

1

मेरे लिए यह ठीक लग रहा है, के लिए छोड़कर:

uint8_t _storage [sizeof(T)/sizeof(uint8_t)]; 

Option (const Option & other) 
    : _embedded (other->_embedded ? new (_storage)T(other->_embedded) : nullptr) 
{ 
} 
+0

'char _storage [sizeof (टी)] के बारे में क्या; 'चूंकि [' char' हमेशा 1] (http://en.cppreference.com/w/cpp/language/sizeof) आकार में है? – Wolf