2013-02-20 73 views
34

मैं दो वैक्टर है:std :: vector की प्रतिलिपि: असाइनमेंट या std :: प्रतिलिपि पसंद करते हैं?

std::vector<int> v1, v2; 

// Filling v1 
... 

और अब मैं v2 को v1 कॉपी करना होगा। वहाँ

v2 = v1;

को

std::copy (v1.begin(), v1.end(), v2.begin());

(या इसके विपरीत) पसंद करते हैं किसी भी कारण है?

+4

असाइनमेंट ऑपरेटर सही काम करेगा। जिस तरह से आपने 'प्रतिलिपि' लिखा है, यह 'v1'' v2' से बड़ा होने पर गड़बड़ हो जाएगा। – jrok

+4

यदि प्रतिलिपि के बाद 'v1' की आवश्यकता नहीं है तो आप केवल' v2.swap (v1); '। – hmjd

+1

लिखें कि आप क्या करना चाहते हैं। यदि आप एक वेक्टर को दूसरे को असाइन करना चाहते हैं, तो उसे लिखें। –

उत्तर

46

आम तौर पर मैं दृढ़ता से v2 = v1 पसंद करेंगे:

  1. यह कम है और इरादा और अधिक स्पष्ट
  2. std::copy अगर v2v1 रूप में एक ही लंबाई नहीं है काम नहीं करेगा बनाता है (ऐसा नहीं होगा इसका आकार बदलें, इसलिए यह पुराने तत्वों में से कुछ को सबसे अच्छा केस बनाए रखेगा (v2.size() > v1.size() और कार्यक्रम में कहीं और इस्तेमाल किए गए कुछ यादृच्छिक डेटा को ओवरराइट करें
  3. यदि v1 समाप्त होने वाला है (और आप सी ++ 11 का उपयोग करते हैं) तो आप आसानी से संशोधित कर सकते हैं यह 012 हैसामग्री
  4. प्रदर्शनवार असाइनमेंट std::copy धीमा होने की संभावना नहीं है, क्योंकि कार्यान्वयनकर्ता संभवतः std::copy आंतरिक रूप से उपयोग करते हैं, अगर यह प्रदर्शन लाभ प्रदान करता है।

निष्कर्ष में, std::copy कम अभिव्यक्तिपूर्ण है, गलत काम कर सकता है और यह भी तेज़ नहीं है। तो यहां इसका उपयोग करने के लिए वास्तव में कोई कारण नहीं है।

+6

फिर, 'std :: copy' के लिए क्या है? – altroware

+12

@altroware: यह सामान्य रूप से एक सीमा से दूसरे तक की प्रतिलिपि बनाने के लिए है। उदाहरण के लिए, आप 'std :: list' से' std :: vector' से कॉपी करने के लिए असाइनमेंट ऑपरेटर का उपयोग नहीं कर सकते हैं, या 'std :: vector' के एक हिस्से से उसी के दूसरे हिस्से में ' std :: vector'। –

+0

क्या होगा यदि v1 को ढेर पर आवंटित किया गया था और नष्ट हो गया था? क्या v1 = v1' v1 के तत्वों की प्रतिलिपि बनाने का कारण बनता है? –

2

यह छोटा है।

std::copy मुख्य रूप से कंटेनर के अनुभागों की प्रतिलिपि बनाने के लिए है। यदि आपको एक संपूर्ण कंटेनर की प्रतिलिपि बनाने की आवश्यकता है, तो आप कॉपी कन्स्ट्रक्टर का भी उपयोग कर सकते हैं।

+0

यदि 'v2' इतना बड़ा नहीं है तो आपको एक बफर ओवररन मिलेगा। –

9

std::copy का आविष्कार गंतव्य वेक्टर के अंत से परे वस्तुओं तक पहुंचने का प्रयास कर सकता है।

असाइनमेंट का उपयोग करें।

माइक्रो-ऑप्टिमाइज़ करने के लिए यह आपका काम नहीं है: यह लाइब्रेरी लेखक की ज़िम्मेदारी है, और अंत में संकलक की ज़िम्मेदारी है।

आप अपने कोड मनमाने ढंग से तेज़ बना सकते हैं यदि यह सही नहीं है।

copy के मामले में, हालांकि, यह संदिग्ध है कि यह भी तेज़ है, और यह सामान्य मामले के लिए निश्चित रूप से सही नहीं है।

+3

मैं अनुकूलन से संबंधित आपके बयान से सहमत हूं, लेकिन यह संकेत दे सकता है कि संकलक या पुस्तकालय के लिए उपलब्ध अधिक जानकारी, बेहतर यह अपना काम कर सकती है। 'Std :: vector' के सदस्य कार्य जानते हैं कि वे' std :: vector' पर काम कर रहे हैं, और जानते हैं कि इसे कैसे कार्यान्वित किया जाता है। 'std :: copy' में यह जानकारी नहीं है। निष्कर्ष यह है कि सदस्य कार्य शायद नौकरी बेहतर कर सकते हैं (और निश्चित रूप से बुरा नहीं)। –

2

असाइनमेंट, दूर तक। अधिक आम तौर पर, किसी भी समय वेक्टर का आकार बदल सकता है, या वेक्टर की पूरी सामग्री को बदल सकता है, आपको सदस्य कार्यों को प्राथमिकता देना चाहिए। केवल std::copy उपयुक्त होगा यदि आप केवल वेक्टर के भीतर पूरी तरह से एक छोटी सी रेंज को बदल रहे हैं।

6

यदि v2 पर्याप्त नहीं है तो आप copy का उपयोग करते समय एक बफर ओवररन प्राप्त करेंगे।

आप एक बैक डालने वाले इटरेटर का उपयोग कर सकते हैं जो v2 पर push_back को कॉल करेगा। हालांकि यह v1 कितना बड़ा है इस पर निर्भर करता है कि यह कई पुनर्विक्रय हो सकता है।

copy(v1.begin(), v1.end(), back_inserter(v2)); 

आप vector सही ढंग से चीजों का प्रबंधन दे से बेहतर कर रहे हैं। असाइनमेंट ऑपरेटर इस करता है, vector::assign करता है:

v2.assign(v1.begin(), v1.end()); 

मैं आभास है कि असाइनमेंट ऑपरेटर vector::assign के मामले में लागू किया गया है है।

+0

श्री वुड, क्या यह संभव है कि v2.assign (v1.begin(), v2.end()) के बजाय आप v2.assign (v1.begin(), v1.end()) का मतलब है? –

+0

@ पीटरस्केफर निश्चित, धन्यवाद –

1

असाइनमेंट स्पष्ट है और आंतरिक रूप से std::copy (या unitizalized_copy_M_allocate_and_copy आकार और क्षमता के आधार पर) का उपयोग करता है या तो प्रदर्शन समान हैं।