2017-02-07 8 views
33

कृपया बताएं कि union और std::variant और std::variant के बीच अंतर क्या है? पुराने परिस्थितियों union पर हमें किन स्थितियों में std::variant का उपयोग करना चाहिए?संघ पर std :: संस्करण का उपयोग कहां करें?

+2

मुझे लगता है कि 'संघ' गैर-पीओडी वस्तुओं को अंदर की अनुमति नहीं देता है। और यहां तक ​​कि अगर यह थोड़े करता है (यानी प्रोग्राम तुरंत क्रैश नहीं होता है), यह सुनिश्चित नहीं करता है कि सही विनाशक कहा जाता है। – yeputons

+9

हर जगह आप टाइप सुरक्षा चाहते हैं और गैर-तुच्छ प्रकारों के साथ काम कर रहे हैं। – user975989

+1

मुझे जेसन टर्नर द्वारा इस वीडियो को देखते हुए std :: संस्करण के बारे में विरोधाभास और गलतफहमी मिली: https: //www.youtube.com/watch? V = 3wm5QzdddYc –

उत्तर

48

सामान्य शब्दों में, आप variant को प्राथमिकता देनी चाहिए जब तक कि निम्न में से एक आता है:

  1. आप को धोखा दे रहे हैं। आप टाइप-पनिंग या अन्य चीजें कर रहे हैं जो यूबी हैं लेकिन आप उम्मीद कर रहे हैं कि आपका कंपाइलर आपके कोड को तोड़ नहीं देगा।

  2. आप कुछ छद्म-पनरी कर रहे हैं कि सी ++ union एस को करने की अनुमति है: लेआउट-संगत प्रकारों या सामान्य प्रारंभिक अनुक्रमों के बीच रूपांतरण।

  3. आपको स्पष्ट रूप से छोटी प्रतिलिपि और/या लेआउट संगतता की आवश्यकता है। variant<Ts> किसी भी विशेष लेआउट या तुच्छ प्रतिलिपि बनाने की आवश्यकता नहीं है। मानक लेआउट प्रकारों के unions मानक लेआउट हैं, और union छोटे-छोटे प्रतिलिपि प्रकारों की तुलनात्मक रूप से कॉपी करने योग्य हैं।

    ध्यान दें कि a proposal to make variant trivially copyable if its component types are trivially copyable है। इसे सी ++ 17 के खिलाफ एक दोष रिपोर्ट के रूप में प्रस्तावित किया गया है, इसलिए इस व्यवहार को प्रभावी ढंग से सी ++ 17 में वापस भेज दिया जाएगा।

  4. आपको ऑब्जेक्ट्स के इन-प्लेस स्विचिंग के लिए निम्न-स्तरीय समर्थन की आवश्यकता है। ऐसी चीजों के लिए मेमोरी बफर का उपयोग करने से तुच्छ प्रतिलिपि गारंटी प्रदान नहीं होती है कि आप union से बाहर निकल सकते हैं।

दोनों के बीच बुनियादी अंतर यह है कि variantजानता जो टाइप यह संग्रहीत करता है, union आपको लगता है कि का ट्रैक रखने के लिए बाहर से उम्मीद है, जबकि है। इसलिए यदि आप variant में गलत आइटम तक पहुंचने का प्रयास करते हैं, तो आपको अपवाद या nullptr मिलता है। इसके विपरीत, union के साथ ऐसा करना केवल अपरिभाषित व्यवहार है।

union निम्न-स्तर का टूल है, और इस प्रकार केवल तभी उपयोग किया जाना चाहिए जब आपको बिल्कुल निम्न स्तर की आवश्यकता हो।

variant भी मुलाक़ात कर रही है, जिसका मतलब है कि जहां "अगर यह प्रकार एक्स है। ऐसा करते हैं तो इसे टाइप वाई है, ऐसा करते हैं, आदि" पूछना आप if बयान का एक समूह होने से बचाने के लिए मिलता है के लिए मशीनरी है।

+10

"केवल अपरिभाषित व्यवहार" एक वाक्यांश नहीं है जिसे मैं अक्सर देखता हूं। :-) * उत्कृष्ट * उत्तर, हालांकि। "धोखाधड़ी" यहां प्राथमिक प्रेरणा है, और लगता है कि इसमें बड़े पैमाने पर 2 और 4 शामिल हैं। –

+2

@ कोडीग्रे: # 2 और # 4 दोनों पूरी तरह से कानूनी हैं। वे वास्तव में धोखाधड़ी की तरह दिखने वाली चीजों के रूप में बहुत धोखा नहीं दे रहे हैं। –

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