दोनों के बीच का अंतर वास्तव में काफी सूक्ष्म है। सी ++ 11 सुविधा सूची प्रारंभ (भी कभी कभी कहा जाता है ब्रेस प्रारंभ) की शुरुआत की:
सी ++ 11 से पहले, जब आप डिफ़ॉल्ट-निर्माण करने के लिए और प्रकार Obj
की o
वस्तु और एक Position p
o
से निर्माण चाहते हैं
Obj o(); // mistake: declares a function o returning an Obj
Obj::Position p(o); // error: no constructor takes a function
012:, आप
Obj o; // default construct o
Obj::Position p(o); // construct p using Position(Obj const&)
लिखना पड़ा शुरुआती (विशेष रूप से एक जावा पृष्ठभूमि के साथ) के लिए एक सामान्य त्रुटि यह लिखने की कोशिश करने के लिए था
पहली पंक्ति function घोषित करती है, और दूसरा एक कन्स्ट्रक्टर का उपयोग करके Position
बनाने का प्रयास करता है जो फ़ंक्शन पॉइंटर को इसके तर्क के रूप में लेता है। आदेश एक समान प्रारंभकर्ता वाक्य रचना करने के लिए, सी ++ 11 शुरू की सूची प्रारंभ:
Obj oo{}; // new in C++11: default construct o of type Obj
Obj::Position p1(oo); // possible before (and after) C++11
Obj::Position p2{oo}; // new in C++11: construct p2 using Position(Obj const&)
इस नई वाक्य रचना भी return
-statements में काम करता है, और यह अपने प्रश्न का जवाब की ओर जाता है: return {*this};
और return *this;
के बीच का अंतर कि पूर्व, *this
से सीधे वापसी मान initializes जबकि बाद पहले धर्मान्तरित *this
एक अस्थायी Position
वस्तु के लिए और फिर परोक्ष रूप से यह अस्थायी से वापसी मान initializes, जो विफल रहता है, क्योंकि दोनों copy- और ले जाने-निर्माता है स्पष्ट रूप से हटा दिया गया है।
जैसा कि पिछले पोस्टर ने नोट किया है, अधिकांश कंपाइलर इन अस्थायी वस्तुओं को बढ़ाते हैं क्योंकि वे वास्तव में कुछ भी उपयोगी नहीं हैं; लेकिन यह केवल तभी संभव है जब उनका सिद्धांत सिद्धांत में उपयोग किया जा सके क्योंकि या तो एक प्रतिलिपि या चालक कन्स्ट्रक्टर उपलब्ध है। क्योंकि इससे बहुत भ्रम पैदा होता है (मुझे अपने रिटर्न स्टेटमेंट के आसपास ब्रेसिज़ की आवश्यकता क्यों है? क्या संकलक प्रतिलिपि बनाने के लिए जा रहा है या नहीं?), सी ++ 17 इन अनावश्यक अस्थायी लोगों से दूर है, और वापसी मूल्य सीधे शुरू करता है दोनों मामलों में (return {*this};
और return *this
)।
आप सी ++ 17 का समर्थन करने वाले एक कंपाइलर का उपयोग करके इसे आजमा सकते हैं। क्लैंग 4.0 या जीसीसी 7.1 में, आप --std=c++1z
पास कर सकते हैं, और आपके कोड को ब्रेसिज़ के साथ और बिना ठीक संकलित करना चाहिए।
मुझे आश्चर्य है कि मैं स्थिति (Obj :: स्थिति &) 'की बजाय त्रुटि में' स्थिति (Obj :: स्थिति &&) ''क्यों देखता हूं, जब मैं ब्रेसिज़ को छोड़ देता हूं। यह विपरीत की तरह दिखता है। – ar2015
@ ar2015 क्या आपका मतलब है कि आप त्रुटि संदेश में 'स्थिति (स्थिति स्थिरांक ') के बजाय' स्थिति (स्थिति &&) 'क्यों देखते हैं? ऐसा इसलिए है क्योंकि आपके पास एक मूल्य 'स्थिति' ऑब्जेक्ट है जिसमें से वापसी मूल्य आरंभ करने के लिए और चालक कन्स्ट्रक्टर एक बेहतर मिलान है। यदि आप 'इनलाइन स्थिति (स्थिति &&) = हटाएं;' पंक्ति पर टिप्पणी करते हैं, तो त्रुटि संदेश में कॉपी कन्स्ट्रक्टर होगा। – Praetorian
यह मूल रूप से "मैंने इसे प्रतिबंधित कर दिया है, तो मैंने ऐसा करने की कोशिश की" यदि वास्तव में इसकी आवश्यकता है – Swift