2015-11-06 8 views
5

जब मैं चाहता हूँ एक समारोह मुझे एक कंटेनर वापस जाने के लिएवापसी मूल्य अनुकूलन: हो सकता है कि मैं विशाल एसटीएल कंटेनर की प्रति निर्माण से बच सकूं।</p> <pre><code>vector<T> func(){ vector<T> result; ... return result; } </code></pre> <p>निम्नलिखित तरीके से इस्तेमाल किया जा करने के लिए::

vector<T> result = func(); 

आदेश मेरा कंटेनर को कॉपी करने की भूमि के ऊपर मैं अक्सर लिखने से बचने के लिए फ़ंक्शन ताकि यह कुछ भी नहीं लौटाए लेकिन कंटेनर के गैर-कॉन्स उदाहरण को स्वीकार करें।

void func(vector<T>& result){ 
    result.clear(); 
    ... 
    result; 
} 

निम्नलिखित तरीके से इस्तेमाल किया जा करने के लिए:

vector<T> result; 
func(result); 

क्योंकि मुझे यकीन है कि संकलक हमेशा वापसी मान अनुकूलन का उपयोग करता है हो सकता है मेरी प्रयास व्यर्थ है?

+1

चूंकि सी ++ 11 आपका प्रयास व्यर्थ है, जब तक सी ++ 11 सही तरीका नहीं है। – 101010

+0

आपको सी ++ 03 में भी अपना पहला कोड उदाहरण उपयोग करना चाहिए। – Simple

+0

आप मानते हैं कि आरवीओ लागू होने पर, दूसरी तरफ उतना ही कुशल होगा। यह हमेशा की घटना नहीं है। –

उत्तर

10

यह व्यर्थ है। आपके द्वारा वर्णित आरवीओ के प्रकार को नामित आरवीओ (एनआरवीओ) कहा जाता है, और अधिकांश कंपाइलर इसे लागू करते हैं।

भले ही, सी ++ 11, vector में रचनाकारों को स्थानांतरित किया गया है, इसलिए यदि एनआरवीओ लागू नहीं हुआ है, तो भी इसे कॉपी किया जाएगा, कॉपी नहीं किया जाएगा।

2

आरवीओ की गारंटी नहीं है लेकिन अनुमति देने पर सभ्य कंपाइलर्स इसका उपयोग करेंगे।

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

2

आपके कंपाइलर की आयु पर निर्भर करता है। सी ++ 11 से पहले, आपका वैकल्पिक दृष्टिकोण तब तक जरूरी है जब तक कि संकलक नाम वापसी मूल्य अनुकूलन का समर्थन नहीं करता - जो सभी पुराने कंपाइलर नहीं करते हैं। साथ ही, आप फ़ंक्शन पास किए गए वेक्टर के संदर्भ को भी वापस कर सकते हैं।

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

+0

यहां तक ​​कि यदि पुराने कंपाइलर का उपयोग करते हैं, तो आप यह देखने के लिए प्रयोग कर सकते हैं कि यह प्रतिलिपि प्रतिलिपि लागू करता है या नहीं। –

+0

दरअसल, एमएम या संकलक दस्तावेज पढ़ें। हालांकि, अभी भी कोड है जिसे ऑपरेटिंग सिस्टम इत्यादि के बीच कई कंपाइलर्स (यहां तक ​​कि कंपाइलर संस्करण और सेटिंग्स) के साथ काम करने की आवश्यकता है। – Peter

0

मैंने इसे जीसीसी के साथ आजमाया है। मुझे एहसास हुआ कि सी ++ 11 झंडे के बिना संकलन करते समय मैं एनआरवीओ पर भरोसा नहीं कर सकता। ,

vector<T> func(){ 
    vector<T> result; 
    ... 
    return result; 
} 

और:

अपने प्राकृतिक रूप में समारोह घोषित:

जब से मैं दूसरे हस्ताक्षर (जहां समारोह संदर्भ द्वारा कंटेनर लेता है) पसंद नहीं है मैं इस के साथ बाहर आया जब मैं संकलक और संकलन झंडे के बारे में निश्चित नहीं हूँ, इस तरह से इसका इस्तेमाल करते हैं: इस तरह से

vector<T> result; 
func().swap(result) 

एक वांछित इंटरफेस हो जाता है और elidible से अधिक से बचने के लिए निश्चित है प्रमुख हैं।

ध्यान दें कि result वेक्टर की क्षमता फ़ंक्शन द्वारा लौटाई गई वेक्टर में से एक है। यदि कोई वेक्टर के लिए क्षमता निर्धारित करना चाहता है, तो फ़ंक्शन के लिए सही इंटरफ़ेस दूसरा है।

+0

एक संदर्भ को स्वैपिंग और पास करने दोनों बदसूरत लगते हैं। आप संदर्भ विधि के साथ भी चिपक सकते हैं। –

+0

आईएमओ स्वैपिंग संदर्भ विधि से बेहतर है क्योंकि स्वैपिंग में घोषणा शामिल नहीं है। फ़ंक्शन का हस्ताक्षर बहुत अधिक पठनीय है (मेरे उदाहरण में कुछ भी वेक्टर नहीं देता है)। – jimifiki

+0

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

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