2014-10-05 5 views
11

std::stack के लिए push() या emplace() का उपयोग करने के बीच अंतर को समझने का प्रयास कर रहा है।सी ++: स्टैक की पुश() बनाम emplace()

मैं सोच रहा था कि अगर मैं std::stack<int> बनाउंगा, तो मैं push() का उपयोग करूंगा क्योंकि पूर्णांक एक आदिम प्रकार है और emplace() के निर्माण के लिए कुछ भी नहीं है।

हालांकि, अगर मैं std::stack<string> बना रहा था तो मैं emplace() चुन सकता था क्योंकि std::string एक ऑब्जेक्ट है।

क्या यह सही उपयोग है?

+0

मैंने पुश_बैक बनाम emplace_back पढ़ा था, या कम से कम करने की कोशिश की थी, लेकिन मुझे आश्चर्य है कि किसी के पास मेरे जैसे किसी के लिए एक सरल उत्तर है जो सी ++ के लिए थोड़ा नया है। –

+4

डुप्लिकेट नहीं। वास्तव में जो पूछ रहा है वह एक एमएसवीसी 10 बग है। यद्यपि यह प्रश्न पहले से ही पूछा जा सकता है, कहीं और, यह वहां नहीं पूछा गया था। –

+0

हर कोई इस emplace_back() चीज़ के बारे में क्यों बात कर रहा है? मुझे C++ 11 emplace() विधि और पुश() का उपयोग करने के बारे में उस बिंदु पर रूचि है। http://www.cplusplus.com/reference/stack/stack/emplace/ – Will

उत्तर

25

पूरी तरह से समझने के लिए कि emplace_back क्या करता है, किसी को सबसे पहले विविध टेम्पलेट्स और रैवल्यू संदर्भों को समझना चाहिए।

यह आधुनिक सी ++ में काफी उन्नत और गहरी अवधारणा है। मानचित्र पर, इसे "ड्रैगन होना चाहिए" लेबल किया जाएगा।

आप कहते हैं कि आप सी ++ के लिए नए हैं और इस सामान को सीखने की कोशिश कर रहे हैं। यह वह उत्तर नहीं हो सकता है जिसे आप ढूंढ रहे हैं, लेकिन आपको अब इस विवरण को छोड़ना चाहिए, और बाद में अपने दिमाग को विविधतापूर्ण टेम्पलेट्स और रैवल्यू संदर्भों के चारों ओर लपेटने के बाद वापस आना चाहिए। तो यह सब समझ में होना चाहिए।

लेकिन यदि आप जोर देते हैं: सरल, प्राथमिक प्रकार जैसे पूर्णांक वाले कंटेनर के लिए, यदि कोई अंतर है, तो बहुत कम है। अंतर तब आता है जब कंटेनर का प्रकार कुछ जटिल, परिष्कृत वर्ग होता है, जिसमें एक जटिल कन्स्ट्रक्टर, और/या कॉपी-कन्स्ट्रक्टर होता है।

या तो धक्का या प्रतिस्थापन का अंतिम परिणाम बिल्कुल 100% है, वही है। कंटेनर को इसमें एक और तत्व जोड़ा जाता है। अंतर यह है कि तत्व कहां से आता है:

1) पुश एक मौजूदा तत्व लेता है, और इसकी एक प्रति कंटेनर में जोड़ता है। सरल, सीधा। धक्का हमेशा कंटेनर में कॉपी करने के लिए तत्व, एक तर्क लेता है।

2) emplace कंटेनर में कक्षा का एक और उदाहरण बनाता है, जो पहले से ही कंटेनर में संलग्न है। इमस्थल के लिए तर्क कंटेनर के वर्ग के कन्स्ट्रक्टर के तर्क के रूप में अग्रेषित किए जाते हैं। यदि कक्षा में एक डिफ़ॉल्ट कन्स्ट्रक्टर है तो इमस्थल में एक तर्क हो सकता है, एक से अधिक तर्क, या कोई तर्क नहीं।

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

तो: यदि आप कंटेनर में कक्षा के मौजूदा उदाहरण की प्रतिलिपि जोड़ना चाहते हैं, तो पुश का उपयोग करें। यदि आप वर्ग के नए उदाहरण को स्क्रैच से बनाना चाहते हैं, तो इमस्थल का उपयोग करें।

+1

मुझे लगता है कि जब मैं प्रतिस्थापन का उपयोग करता हूं तो मैं समझता हूं कि मैं पुश का उपयोग करता हूं। मैं निश्चित रूप से विविध टेम्पलेट्स और रैवल्यू संदर्भों पर जानकारी देख रहा हूं। –

+0

'emplace' का उपयोग करके हमेशा हमेशा फ्लैट-आउट करने के लिए कोई नकारात्मक पक्ष होगा, भले ही मैं जिस वस्तु को जोड़ना चाहता हूं वह पहले से मौजूद है? – antred

+1

@antred - push_back() समान प्रारंभिक वाक्यविन्यास की अनुमति देता है। emplace_back(), यह देखते हुए कि यह एक टेम्पलेट फ़ंक्शन है, नहीं। –

10

यदि आपके पास vector<X> है, तो emplace_back(a, b, c) वेक्टर के अंदर X ऑब्जेक्ट बनाता है।

इसके विपरीत, push_back(X(a, b, c)) पहले एक अस्थायी बनाता है, जिसे तब वेक्टर में स्थानांतरित किया जाता है।

+0

फिर, 'emplace_back (एक्स (ए, बी, सी)) के बारे में क्या? – avocado

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