2010-07-09 12 views
6

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

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

+0

यह रनटाइम बहुरूपता से निपटने का एक तरीका दिखाता है। मुझे लगता है कि यह संबंधित है। https://youtu.be/vxv74Mjt9_0?t=16m8s –

+0

संभावित डुप्लिकेट [मैं सी ++ कंटेनर में अलग-अलग प्रकार की वस्तुओं को कैसे स्टोर कर सकता हूं?] (Https://stackoverflow.com/questions/4738405/how-can- i-store-items-of-differing-type-in-ac-container) –

उत्तर

7

बूस्ट लाइब्रेरी शायद आप जो खोज रहे हैं (boost :: any)। यदि आप बूस्ट का उपयोग नहीं कर सकते हैं तो आप एक लिपटे पॉइंटर दृष्टिकोण का उपयोग करके अपना खुद का रोल कर सकते हैं ...

+1

धन्यवाद! मुझे लगता है कि "कोई भी" काम करेगा! मुझे बूस्ट :: किसी भी के आधार पर इस पर एक ट्यूटोरियल भी मिला। यहां यह है, अगर किसी को इसकी ज़रूरत है! http://www.devx.com/cplus/10MinuteSolution/29757/1954 – Abhi

0

मैं सोच रहा था कि आप केवल एक जोड़ी (प्रकार, शून्य *) प्राप्त कर सकते हैं और अपना स्वयं का पॉप फ़ंक्शन लिख सकते हैं जो शून्य * पर निर्भर करता है जोड़ी में वर्णन करते हैं और फिर इन्हें जो भी कंटेनर आपकी आंख पकड़ता है उसे फेंक दें।

+0

जैसा कि नील द्वारा उल्लिखित है, त्रुटि प्रवण और अक्षम, मैं भी इसकी अनुशंसा नहीं करता। या तो नील के सुझाव का पालन करें और केवल विरासत का उपयोग करें या 6502 द्वारा उपरोक्त किसी भी बूस्ट :: को देखें। – cjh

4

इस तरह के कंटेनरों के साथ समस्या यह है कि जब आप कंटेनर में कुछ एक्सेस करना चाहते हैं, तो आपको इसके प्रकार का निर्धारण करना होगा और फिर इसे किसी भी प्रकार वास्तविक प्रकार में डालना होगा। यह बदसूरत, अक्षम और त्रुटि-प्रवण है, यही कारण है कि सी ++ में # 1 विकल्प विरासत का उपयोग करना है, जब तक कि आपके पास बहुत अच्छा कारण न हो - ऐसा कुछ जो मैंने कभी भी मेरे सी ++ करियर में नहीं देखा है।

+0

धन्यवाद नील! ... तो ये डेटा-प्रकार मूल रूप से सभी जगह पर हैं, यदि आप चाहें तो knobs का एक सेट हैं । वे लंबे int, स्ट्रिंग, बूल, और इतने पर हो सकते हैं :(विरासत का उपयोग नहीं कर सकते .. – Abhi

+1

वैक्टर और सी ++ कक्षाओं के साथ समस्या यह है कि आप बेस के वेक्टर घोषित नहीं कर सकते हैं और फिर अंदर व्युत्पन्न के उदाहरण डाल सकते हैं। सी ++ के दर्शन की प्रतिलिपि std :: vector (या किसी अन्य std :: कंटेनर) के लिए इस तरह के किसी भी कार्यान्वयन के लिए पॉइंटर्स (अंततः लपेटा हुआ) का उपयोग करना चाहिए। – 6502

+1

@ एबी वास्तव में आप विरासत का उपयोग कर सकते हैं, यह है कि कैसे :: किसी भी काम को बढ़ावा देता है, यह मिटा देता है एक निजी आधार में टाइप करें जिसमें टेम्पलेट व्युत्पन्न प्रकार है जिसमें मूल्य शामिल हैं, यह सब बूस्ट के अंदर छिपी हुई है :: जहां भी यह कन्स्ट्रक्टर/असाइनमेंट ऑपरेटर टाइप मिटा रहा है (वे टेम्पलेट्स हैं)। हालांकि मैं आपको अपने डिजाइन पर पुनर्विचार करने का सुझाव देता हूं, वास्तव में इसकी ज़रूरत है। –

9

boost::any पहले से ही अनुशंसित किया गया है, हालांकि यह किसी भी चीज़ के लिए है, इसलिए आप इससे अधिक उम्मीद नहीं कर सकते हैं।

यदि आप समय से पहले विभिन्न प्रकारों को जानते हैं, तो आप बेहतर boost::variant का उपयोग कर रहे हैं।

typedef boost::variant<Foo, Bar, Joe> variant_type; 

struct Print: boost::static_visitor<> 
{ 
    void operator()(Foo const& f) const { f.print(std::cout); } 

    template <class T> 
    void operator()(T const& t) const { std::cout << t << '\n'; } 
}; 

void func(variant_type const& v) // not template 
{ 
    boost::apply_visitor(Print(), v); // compile-time checking 
            // that all types are handled 
} 
संबंधित मुद्दे