2016-01-14 17 views
10

मैं तर्क भरने के लिए सबसे अच्छा प्रभावी तरीका के बारे में पूरे दिन पढ़ रहा हूं और मैं उलझन में हूं। मैं इस तरह एक सदिश पास करना चाहते हैं:सी ++ 11 पास वेक्टर निर्माता

Foo f({1,2,3}); 

मैं सिर्फ पारित किया वेक्टर के साथ मेरी _member चर को प्रारंभ करना चाहते हैं। अब सवाल यह है कि कैसे करना चाहिए मेरी निर्माता देखो:

// pass by value 
Foo (vector<int> vec) : _member{vec} {} 

// const reference 
Foo (const vector<int>& vec) : _member{vec} {} 

// rvalue reference 
Foo (vector<int>&& vec) : _member{std::move(vec)} {} 
+2

आपके पास-बाय-वैल्यू में 'std :: move' होना चाहिए, साथ ही – CoffeeandCode

+0

वेक्टर के रूप में नए वेक्टर को प्रारंभ करना चाहिए और इसे –

उत्तर

10

सरल दृष्टिकोण मूल्य द्वारा वेक्टर लेते हैं, और ले जाने के लिए है:

Foo (vector<int> vec) : _member{std::move(vec)} {} 

const vector<int>&/vector<int>&& भार के की एक जोड़ी की तुलना में, आप एक अतिरिक्त कदम (जो वैक्टरों के लिए बहुत सस्ता है) तक भुगतान करें, लेकिन दो रचनाकारों को लिखने की ज़रूरत नहीं है (यदि आपके पास एक से अधिक पैरामीटर हैं तो बहुत तेज़ी से विस्फोट कर सकते हैं)।

+0

पास करें 'अतिरिक्त' चाल से आपका क्या मतलब है? क्या तुलना में? – SergeyA

+0

धन्यवाद @ टी.सी. एक और सवाल: जब इसका इस्तेमाल किया जाना चाहिए? केवल अगर हम बड़े वैक्टर या हर समय पास करते हैं? मेरा मतलब है छोटे वैक्टरों के लिए उदाहरण के लिए मानक तरीका क्या होगा? – Petrof

+0

@ पेट्रोफ यह छोटे और बड़े वैक्टरों के लिए समान रूप से अच्छी तरह से काम करता है। –

0

इस विशेष मामले में, आप rvalue पास कर रहे हैं, इसलिए तीसरा विकल्प सबसे अच्छा है।

+0

क्योंकि एक कॉलर प्रत्येक कॉलर का प्रतिनिधित्व करता है? – ildjarn

+0

बेशक नहीं, लेकिन चूंकि वह एक विशिष्ट उदाहरण प्रदान कर रहा है, मुझे विश्वास है कि यह उदाहरण-विशिष्ट सर्वोत्तम विकल्प भी है। – ViNi89

2

मूल्य से गुजरना आजकल कई सर्किलों में आधुनिक है। मुझे लगता है कि विभिन्न कारणों से रचनाकारों के लिए यह एक अच्छा विकल्प है, इसलिए मैं टीसी के जवाब से सहमत हूं। हालांकि, तर्क (गैर-रचनात्मक कार्यों के लिए) पास करने का सबसे अच्छा तरीका व्यापक प्रश्न, मैं शायद ही कभी मूल्य से गुजरने की अनुशंसा करता हूं। मैं वास्तव में, वास्तव में दृढ़ता से दृढ़ता से विषय पर हर्ब सटर से एक बात के इस हिस्से को सुनने की सलाह देता हूं: https://youtu.be/xnqTKD8uD64?t=51m34s

संक्षेप में, रचनाकारों के बाहर संक्षेप में: मूल्य से गुजरने से कॉन्स-रेफ द्वारा सरल पास की तुलना में सबसे खराब स्थिति प्रदर्शन गारंटी देता है, यह सभी मामलों में कॉन्स्ट-रेफ/रावल्यू-रेफ ओवरलोड से भी खराब प्रदर्शन देता है, यह इसे बनाता है अपवाद गारंटी देने के लिए कठिन है, यह polymorphic प्रकार स्लाइस, इसका उपयोग नहीं किया जा सकता है जब प्रतिलिपि सशर्त है।

ज्यादातर स्थितियों में, आप या तो कारण के भीतर प्रदर्शन की परवाह नहीं करते हैं, या आप बहुत परवाह करते हैं। पहले मामले में, कॉन्स्ट-रेफ का उपयोग करना सरल और आसान है। दूसरे मामले में, मूल्य से गुजरना पर्याप्त नहीं है। दोबारा, ध्यान रखें कि रचनाकार कुछ अलग-अलग कारणों से अलग हैं (वे असाइन करने के बजाए चीजों का निर्माण कर रहे हैं, वे कई तर्क लेते हैं जो आपको आवश्यक अधिभारों की संख्या को दृढ़ता से प्रभावित करते हैं)।

दुर्भाग्य से इस प्रश्न का इतना आसान एकल जवाब नहीं है। आखिरकार दोनों दृष्टिकोण काफी अच्छे हैं, लेकिन मुझे लगता है कि सी ++ मास्टर करना चाहते हैं, आप दोनों के पेशेवरों और विपक्ष को जानना चाहते हैं।

+0

उत्तर के लिए धन्यवाद।मुझे लगता है कि मैं इस [लिंक] (http://stackoverflow.com/questions/32810939/c-lvalues-rvalues-references-parameters-and-performance) के आधार पर गैर-कन्स्ट्रक्टर फ़ंक्शन को समझता हूं। मेरी समस्या कन्स्ट्रक्टर और टीसी के साथ थी। जवाब ने मुझे समझने में बहुत मदद की। मैं निश्चित रूप से उस वीडियो की जांच करूँगा, धन्यवाद। – Petrof

+0

"* मूल्य से गुजरना कॉन्स-रेफ * द्वारा सरल पास की तुलना में खराब सबसे खराब केस प्रदर्शन गारंटी देता है" जब तक आपको किसी प्रतिलिपि की आवश्यकता न हो; सटर एक ही बात कहता है। "* यह सभी मामलों में कॉन्स-रेफ/रावल्यू-रेफ ओवरलोड की तुलना में खराब प्रदर्शन देता है *" केवल कई मामलों में एक कदम की लागत से, लेकिन यह हमेशा कोड से दोगुना होता है। "* यह अपवाद गारंटी देने में कठिन बनाता है *" वास्तव में, यह उन्हें आसान बनाता है क्योंकि बोझ कॉलर को स्थानांतरित कर दिया जाता है। "* यह polymorphic प्रकार स्लाइस * * पूरी तरह से ऑर्थोगोनल मुद्दा। "* इसका उपयोग तब नहीं किया जा सकता जब प्रतिलिपि सशर्त हो * * बिंदु एक देखें। – ildjarn

+0

सशर्तता और बहुरूपता आपके सिर में रखने के लिए केवल अतिरिक्त विशेष मामले हैं, इसलिए वे चीजों को और अधिक जटिल बनाते हैं। आम तौर पर, प्रदर्शन महत्वपूर्ण नहीं होता है, और जब प्रदर्शन महत्वपूर्ण नहीं होता है, तो कॉन्स रेफरी आपके डिफ़ॉल्ट पर जाना चाहिए। प्रदर्शन के लिए, यह * नहीं * क्या सटर कहते हैं। सटर प्रतिलिपि की प्रतिलिपि बनाने के लिए कॉपी निर्माण (पास-बाय-वैल्यू) की तुलना करता है (पास-बाय-कॉन्स्ट-रेफ); और नोट करता है कि सामान्य प्रकार (वेक्टर/स्ट्रिंग) प्रति असाइनमेंट के लिए कई व्यावहारिक उपयोग मामलों में * महत्वपूर्ण * सस्ता है। दूसरे शब्दों में: यदि हम perf को अनदेखा करते हैं तो मूल्य से गुजरना स्पष्ट रूप से खराब होता है, और यह भी perf के लिए अच्छा नहीं है। –

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