दिलचस्प पोस्ट
दिनांक समय के लिए सी # स्ट्रिंग पार्स करें दो चरण प्रसंस्करण: चरण 1 XSLT 2.0 प्रोसेसिंग से रिक्त टैग आउटपुट न करें एंड्रॉइड / जावा: कैसे एक विधि में वापसी देरी JVM प्रोजेक्ट को जावा एप्लिकेशन से रनटाइम.एक्सएसी का इस्तेमाल करना चाहिए? सभी खाली लाइनों को हटा दें एक शब्दकोश की प्रतिलिपि कैसे करें और केवल प्रतिलिपि संपादित करें जावा प्रोग्रामिंग में जावास्क्रिप्ट कैसे चलाना है दस्तावेज़ तैयार करने वाले कोण नियंत्रक में फ़ंक्शन कैसे चलाना है? मूल्य द्वारा PHP बहुआयामी सरणी खोज JavaFX सही स्केलिंग संग्रहित प्रक्रियाओं / फ़ंक्शंस की सूची MySQL कमांड लाइन पर्ल के आईएनसी का निर्माण कैसे किया जाता है? (उर्फ क्या पर्ल मॉड्यूल की खोज करने के सभी तरीके क्या हैं?) एंड्रॉइड पर मैं मीडियास्टोर को कैसे रिफ्रेश कर सकता हूं? क्या एक्सएसएलटी में स्प्लिट () फ़ंक्शन है? sqlite3.ऑपरेशन त्रुटि: निकट "?": सिंटैक्स त्रुटि

फ़ंक्शन से अनन्य आईपीटीआर रिटर्निंग

unique_ptr<T> प्रतिलिपि निर्माण की अनुमति नहीं देता है, इसके बदले यह चाल शब्दों का समर्थन करता है। फिर भी, मैं फ़ंक्शन से एक unique_ptr<T> वापस कर सकता हूं और लौटा हुआ मान को किसी चर में आवंटित कर सकता हूं।

 #include <iostream> #include <memory> using namespace std; unique_ptr<int> foo() { unique_ptr<int> p( new int(10) ); return p; // 1 //return move( p ); // 2 } int main() { unique_ptr<int> p = foo(); cout << *p << endl; return 0; } 

कोड के ऊपर संकलन और काम के रूप में इरादा। तो यह कैसे है कि लाइन 1 प्रतिलिपि कन्स्ट्रक्टर का आह्वान नहीं करता है और कम्पाइलर त्रुटियों का परिणाम है? यदि मुझे लाइन 2 का उपयोग करना पड़ता है, बजाय यह समझ में आता है (पंक्ति 2 साथ-साथ काम करता है, लेकिन हमें ऐसा करने की आवश्यकता नहीं है)।

मुझे पता है कि सी ++ 0x इस अपवाद को unique_ptr को अनुमति देता है क्योंकि रिटर्न वैल्यू एक अस्थायी ऑब्जेक्ट है, जो समारोह के बाहर निकलती है जैसे कि नष्ट हो जाएगी, इस प्रकार लौटा सूचक की विशिष्टता की गारंटी देता है। मैं इस बारे में उत्सुक हूँ कि यह कैसे लागू किया गया है, क्या यह विशेष रूप से संकलक में लगाया गया है या क्या उस भाषा के विनिर्देशन में कुछ अन्य खंड है जो इसका उपयोग करता है?

Solutions Collecting From Web of "फ़ंक्शन से अनन्य आईपीटीआर रिटर्निंग"

क्या भाषा विनिर्देश में कुछ अन्य खंड है जो इसका फायदा उठाता है?

हां, 12.8 § 34 और § 35 देखें:

जब कुछ मानदंड मिलते हैं, तो एक कार्यान्वयन को किसी वस्तु के प्रतिलिपि / स्थानांतरित निर्माण को रद्द करने की अनुमति दी जाती है […] प्रतिलिपि / स्थानांतरित ऑपरेशन की प्रतिलिपि, जिसे कॉपी एलिजन कहा जाता है , को अनुमति […] में एक रिटर्न स्टेटमेंट में एक वर्ग वापसी प्रकार के साथ एक फ़ंक्शन, जब अभिव्यक्ति एक गैर-वाष्पशील स्वचालित ऑब्जेक्ट का नाम है , जैसे कि सीवी-अयोग्य प्रकार के फ़ंक्शन रिटर्न प्रकार […]

जब प्रतिलिपि ऑपरेशन की पूर्ति के लिए मापदंड पूरा हो जाता है और प्रतिलिपि करने वाली ऑब्जेक्ट को एक लावल्यू द्वारा नामित किया जाता है, प्रतिलिपि के लिए कन्स्ट्रक्टर का चयन करने के लिए ओवरलोड रिज़ॉल्यूशन पहली बार किया जाता है जैसे ऑब्जेक्ट को एक रैवल्यू द्वारा निर्दिष्ट किया गया था


सिर्फ एक और बिंदु जोड़ना चाहती थी कि मूल्य से लौटने का यह मूल विकल्प होना चाहिए क्योंकि सबसे खराब स्थिति में रिटर्न स्टेटमेंट में नामांकित मान, अर्थात सी ++ 11, सी ++ 14 और सी ++ 17 में बिना किसी श्रेणी में एक रैवल्यू के रूप में इसलिए उदाहरण के लिए निम्न -fno-elide-constructors ध्वज के साथ संकलित

 std::unique_ptr<int> get_unique() { auto ptr = std::unique_ptr<int>{new int{2}}; // <- 1 return ptr; // <- 2, moved into the to be returned unique_ptr } ... auto int_uptr = get_unique(); // <- 3 

संकलन पर सेट ध्वज के साथ इस समारोह में दो कदम (1 और 2) हो रहे हैं और फिर बाद में एक कदम (3)।

यह अनोखी _पीटीआर के लिए विशिष्ट नहीं है, लेकिन चलने वाले किसी भी वर्ग पर लागू होता है। जब आप मूल्य से लौट रहे हैं, तब से भाषा के नियमों की गारंटी दी जाती है कंपाइलर प्रतिलिपियों को समाप्त करने की कोशिश करता है, एक चालन निर्माता को आमंत्रित करता है यदि वह प्रतियां नहीं निकाल सकता, तो एक प्रति कन्स्ट्रक्टर को कॉल करता है, यदि वह चाल नहीं सकता है, और अगर वह प्रतिलिपि नहीं कर सकता है तो उसे संकलित करने में विफल रहता है।

यदि आपके पास फ़ंक्शन है जो अद्वितीय_प्रतिक को एक तर्क के रूप में स्वीकार करता है तो आप इसे पी पास नहीं कर पाएंगे। आपको स्पष्ट रूप से चालन निर्माता चालान करना होगा, लेकिन इस मामले में आपको कॉल से बार के बाद चर पी का उपयोग नहीं करना चाहिए ()।

 void bar(std::unique_ptr<int> p) { } int main() { unique_ptr<int> p = foo(); bar(p); // error, can't implicitly invoke move constructor on lvalue bar(std::move(p)); // OK but don't use p afterwards } 

अनूठे_प्रतिक में पारंपरिक प्रतिलिपि निर्माता नहीं है इसके बजाय इसमें एक "चाल रचनाकार" है जो कि rvalue संदर्भों का उपयोग करता है:

 unique_ptr::unique_ptr(unique_ptr && src); 

एक रैवल्यू संदर्भ (डबल एम्परसेंड) केवल एक रैवल्यू के लिए बाध्य होगा यही कारण है कि जब आप किसी फ़ंक्शन पर lvalue unique_ptr पास करने का प्रयास करते हैं तो आपको एक त्रुटि मिलती है। दूसरी ओर, किसी फ़ंक्शन से लौटाए जाने वाले मान को एक रवैये के रूप में माना जाता है, इसलिए स्थानांतरण निर्माता को स्वचालित रूप से कहा जाता है।

वैसे, यह सही तरीके से काम करेगा:

 bar(unique_ptr<int>(new int(44)); 

अस्थायी अनूठा_प्रकाश यहां एक रैवल्यू है।

एक बात जो मैंने अन्य उत्तरों में नहीं देखी है अन्य उत्तरों को स्पष्ट करने के लिए कि एक समारोह के भीतर बनाया गया std :: unique_ptr और उस समारोह को दिया गया एक के बीच अंतर है।

इसका उदाहरण हो सकता है:

 class Test {int i;}; std::unique_ptr<Test> foo1() { std::unique_ptr<Test> res(new Test); return res; } std::unique_ptr<Test> foo2(std::unique_ptr<Test>&& t) { // return t; // this will produce an error! return std::move(t); } //... auto test1=foo1(); auto test2=foo2(std::unique_ptr<Test>(new Test)); 

मुझे लगता है कि यह स्कॉट मैयर्स के प्रभावी आधुनिक सी ++ के आइटम 25 में पूरी तरह समझाया गया है । यहां एक अंश है:

आर.वी.ओ के आशीर्वाद वाले स्टैंडर्ड का हिस्सा कहने पर चला जाता है कि यदि आरवीओ की शर्तों को पूरा किया जाता है, लेकिन संकलक प्रतिलिपि को नहीं करने का चयन करते हैं, तो वस्तु वापस लौटाई जानी चाहिए एक मूल्य के रूप में माना जाएगा। असल में मानक को यह अपेक्षा की जाती है कि जब आरवीओ की अनुमति दी जाती है, या तो एलियेशन का प्रतिलिपि होता है या std::move होने पर स्थानीय ऑब्जेक्ट्स को वापस लौटा दिया जाता है

यहां, आरवीओ का मूल्य मूल्य अनुकूलन को दर्शाता है, और यदि आरवीओ के लिए शर्तें पूरी होती हैं तो उस समारोह के अंदर घोषित स्थानीय ऑब्जेक्ट को लौटाने का मतलब है जिसे आप आरवीओ करना चाहते हैं, जिसे भी अपनी पुस्तक की आइटम 25 में समझाया गया है मानक (यहां स्थानीय ऑब्जेक्ट रिटर्न स्टेटमेंट द्वारा बनाए गए अस्थायी वस्तुओं को शामिल करता है) अंश से दूर लेना सबसे बड़ी है या तो प्रतिलिपि एलियंस होती है या std::move स्थानीय आदान- std::move लिए निहित रूप से लागू होती है स्कॉट ने आइटम 25 में उल्लेख किया है कि std::move पूर्णतः लागू होता है जब संकलक प्रतिलिपि को दूर न करने का चयन करता है और प्रोग्रामर को स्पष्ट रूप से ऐसा नहीं करना चाहिए।

आपके मामले में, कोड स्पष्ट रूप से आरवीओ के लिए एक उम्मीदवार है क्योंकि यह स्थानीय ऑब्जेक्ट p और p का प्रकार वापसी प्रकार के समान होता है, जिसके परिणामस्वरूप एलआईसी की प्रतिलिपि होती है और अगर कंपाइलर प्रतिलिपि को दूर करने के लिए नहीं चुनता है, तो किसी भी कारण से, std::move करने के लिए लाइन 1 में लात मार दिया होगा।