अंतर यह है कि ++a
एक अंतराल है, हालांकि a++
नहीं है। यह द्वारा सी ++ 14 [expr.pre.incr]/1 निर्दिष्ट किया जाता है:
उपसर्ग ++
के संकार्य 1 जोड़कर संशोधित किया गया है [...] संकार्य एक परिवर्तनीय lvalue होगा। [...] परिणाम अद्यतन ऑपरेंड है; यह एक lvalue है
और [expr.post.incr]/1:
[...] परिणाम एक prvalue है।
अब हम auto && b = ++a;
पर विचार करें। ++a
एक लाभा है। auto&&
एक अग्रेषण संदर्भ है। फॉरवर्डिंग संदर्भ वास्तव में अंतराल से जुड़ सकते हैं: auto
स्वयं संदर्भ प्रकार को घटा सकता है। यह कोड int &b = ++a;
पर घटा देता है।
जब कोई संदर्भ उसी प्रकार के अंतराल से बंधे होते हैं, तो संदर्भ सीधे बाध्य होता है, इसलिए b
a
के लिए एक और नाम बन जाता है।
दूसरे उदाहरण में, auto && b = a++;
, a++
एक prvalue है। इसका मतलब है कि इसमें कोई संबंधित पता नहीं है और यह अब a
परिवर्तनीय से संबंधित नहीं है। इस पंक्ति में ++a; auto && b = (a + 0);
के समान व्यवहार है।
सबसे पहले, a++
एक प्रावधान है, auto&&
int&&
पर deduces। (यानी auto
int
को घटा देता है)। जब गैर-वर्ग प्रकार का संदर्भ किसी प्रक्षेपण के लिए बाध्य होता है, तो एक अस्थायी वस्तु मूल्य से प्रति-प्रारंभ की जाती है। संदर्भ के मिलान के लिए इस वस्तु का जीवनकाल बढ़ा है।
तो दूसरे मामले में b
a
से एक अलग वस्तु के लिए बाध्य है, एक "अस्थायी" पूर्णांक (जो वास्तव में तो अस्थायी नहीं है, क्योंकि यह रूप में लंबे समय b
करता है के रूप में रहता है)।
संदर्भ बाध्यकारी नियम [dcl.init.ref] में हैं।
स्रोत
2016-02-10 13:10:51
मैं आपको एक संकेत दूंगा - 'ए 'एक रावल नहीं है। – erip
@erip हां, मुझे पता है, लेकिन 'बी' के लिए दो उदाहरणों में क्या अंतर है? – vladon
दूसरे उदाहरण में 'बी' पहले उदाहरण की तरह पहले इसे बढ़ाने के बिना 'ए' का मान प्राप्त करता है। – x13