2017-02-13 9 views
5

में कक्षा के सदस्य के रूप में वितरण कक्षाओं के भीतर वितरण के उपयोग से संबंधित मेरे दो संबंधित प्रश्न हैं।सी ++

  1. वहाँ आदेश यह जानकर कि किस वितरण यह हो जाएगा के बिना एक वर्ग के सदस्य के रूप में एक वितरण का उपयोग करने के सी में आधार वितरण ++ किसी तरह का है? मैं टेम्पलेट का उपयोग नहीं कर सकते हैं (प्रश्न 2 देखें)

    class Foo{ 
        private: 
         // could by any distribution 
         std::base_distribution dist_; 
    
    }; 
    
  2. मैं किसी अन्य वर्ग Bar है कि एक निजी सदस्य (std::vector<Foo>) के रूप में Foo का एक वेक्टर होना चाहिए है। समस्या यह है कि यदि Foo टेम्पलेट का उपयोग करता है, तो अलग-अलग टेम्पलेट तर्कों का वेक्टर होना संभव नहीं है जो मैं चाहता हूं।

    class Bar { 
        private: 
         std::vector<Foo> foo_; 
    
    }; 
    

boost::variant मदद नहीं करता है, क्योंकि या तो मैं वितरण के प्रकार पता नहीं है। तो यह (उदाहरण के लिए) मेरे मामले में संभव नहीं है:

class Bar{ 
    private: 
     boost::variant<std::normal_distribution<>, std::uniform_real_distribution<> > dists_; 
}; 
+0

यदि आपको केवल एक प्रकार के यादृच्छिक संख्या इंजन का समर्थन करने की आवश्यकता है, तो 'std :: function' पर्याप्त हो सकता है। –

उत्तर

8

नहीं, सभी वितरण टेम्पलेट्स द्वारा साझा कोई आधार वर्ग नहीं है। यहां तक ​​कि यदि वहां थे, तो आपका इच्छित दृष्टिकोण because of object slicing पर काम नहीं करेगा।

हालांकि, यह अपनी खुद की बेस क्लास बनाने के लिए काफी आसान होना चाहिए, और इससे प्राप्त करना चाहिए।

class base_distribution {}; 

template<typename ...Args> class normal_distribution : 
public base_distribution, public std::normal_distribution<Args...> {}; 

template<typename ...Args> class uniform_int_distribution : 
public base_distribution, public std::inform_int_distribution<Args...> {}; 

... और इसी तरह, जो भी वितरण आप समर्थन करना चाहते हैं। अधिकतम पारदर्शिता के लिए आपको शायद अपने वास्तविक वितरण बेस क्लास में रैपर के रचनाकारों को भी प्रतिनिधि करने की आवश्यकता होगी।

इस बिंदु पर, ऑब्जेक्ट स्लाइसिंग एक कारक बन जाती है, इसलिए आप किसी सदस्य के रूप में base_distribution को कक्षा में नहीं डाल सकते हैं, या इसे वेक्टर में फेंक सकते हैं, और इसे काम करने की उम्मीद कर सकते हैं। आपको कम से कम

std::shared_ptr<base_distribution> 

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

+0

आप 'std :: unique_ptr ' का उपयोग करने में सक्षम हो सकते हैं। –

+0

@ मार्टिनबोनर को बेस क्लास को आभासी विनाशक देने की आवश्यकता है। –

+0

यह करता है।मैं भूल जाता हूं कि स्मार्ट पॉइंटर्स में से एक ऑब्जेक्ट के प्रकार को निर्माण समय पर कैप्चर कर सकता है, और उसके बाद सही ढंग से इसे हटा सकता है, भले ही अंतिम सूचक प्रकार बेस है और विनाशक गैर-वर्चुअल है। मुझे यह सुनिश्चित करने के लिए देखना होगा कि यह 'shared_ptr' था - लेकिन एक आभासी विनाशक हमेशा सुरक्षित समाधान है। –

1

मेरी जानकारी के लिए, सी में, कोई "आधार वितरण वर्ग" या सामान्य वितरण वर्ग ++ है। आपके पास RandomNumberDistribution concept है, लेकिन यह स्पष्ट रूप से वही बात नहीं है।

यदि आप त्वरित और गंदे वितरण वर्ग चाहते हैं (और मेरा मतलब गंदे है), तो मैं वर्तमान में ऐसा कुछ उपयोग करता हूं (.h, .cpp)।

आपके दूसरे प्रश्न के लिए - आपको अपने टेम्पलेट क्लास को एक गैर-टेम्पलेटेड क्लास से प्राप्त करने की आवश्यकता हो सकती है जिसे आप अपने वेक्टर में रख सकते हैं (आपको डेटा स्लाइसिंग से बचने के लिए पॉइंटर सदस्यों का उपयोग करने की आवश्यकता होगी)।

+0

@ मार्टिनबोनर: वास्तव में मेरा मतलब था। मैंने गलती से उस सुझाव को एक सुझाव की तरह दिया। धन्यवाद। – einpoklum