2016-12-16 12 views
27

const auto& [a, b] = f(); लिख रहा है f() से लौटे ऑब्जेक्ट के जीवनकाल को विस्तारित करने की गारंटी, या कम से कम ऑब्जेक्ट a और b बाध्य हैं? the proposal के माध्यम से पढ़ना मुझे यह सुनिश्चित करने के लिए भाषा में कुछ भी स्पष्ट नहीं दिख रहा है कि यह तब तक करता है जब तक कि यह किसी अन्य चीज़ से ढंका न हो। हालांकि, निम्नलिखित अस्थायी के जीवन का विस्तार नहीं है, इसलिए मैं नहीं दिख रहा है कि यह कैसे कवर किया जाएगा:संरचित बाइंडिंग में कॉन्स संदर्भों को विघटित वस्तु का जीवनकाल बढ़ाएं?

const auto& a = std::get<0>(f()); 

कागज यह पता चलता है कि यह कवर किया जाता है लगता है के शीर्ष पर

सीवी-क्वालिफायर और अपघटन घोषणा के रेफरी-क्वालीफायर संदर्भ प्रारंभकर्ता के लिए शुरू की पर लागू होते हैं, न कि व्यक्तिगत सदस्य के लिए उपनाम

लेकिन वास्तविक मानक, निकटतम उल्लेख के लिए प्रस्तावित शब्दों में मैं बेलो देखता हूँ डब्ल्यू, हालांकि मुझे यकीन है कि कैसे इसे पढ़ने के लिए गारंटी मैं तलाश कर रहा हूँ प्राप्त करने के लिए नहीं कर रहा हूँ: अगर ई एक unparenthesized आईडी अभिव्यक्ति एक lvalue या संदर्भ एक के पहचानकर्ता-सूची से शुरू नामकरण है

अपघटन घोषणा, decltype (ई) संदर्भित प्रकार के विनिर्देश में दिए गए अपघटन घोषणा

ऐसा लगता है कि जीसीसी और बजना दोनों वस्तु के जीवन का विस्तार जब तक के आधार पर गुंजाइश के अंत के रूप में लौट आए है एक wandbox experiment। एक uglier one अपने स्वयं के प्रकार के लिए सभी घंटियां और सीटी लागू करने से बाहरी वस्तु और उसके अन्य डेटा सदस्यों का जीवनकाल बढ़ता प्रतीत होता है।

हालांकि लगभग निश्चित रूप से लेखकों के इरादे, मैं यह सुनिश्चित करना चाहता हूं कि भाषा गारंटी है कि यह सुरक्षित है।

उत्तर

17

हां। यह चाल यह जानना है कि उपस्थिति के बावजूद, [ से पहले संरचित बाध्यकारी घोषणा का हिस्सा पहचानकर्ता-सूची में नामों पर लागू नहीं होता है। वे घोषणापत्र के बजाय निहित वैरिएबल के बजाय आवेदन करते हैं। [dcl.struct.bind]/1:

सबसे पहले, एक अद्वितीय नाम e के साथ एक चर प्रस्तुत किया गया है। की इसी तत्व से-प्रारंभ प्रत्यक्ष प्रारंभकर्ता में काम अभिव्यक्ति सरणी प्रकार A है और कोई रेफरी-क्वालीफायर मौजूद है, e टाइप cv A है और प्रत्येक तत्व कॉपी-प्रारंभ या है प्रारंभकर्ता के रूप में निर्दिष्ट असाइनमेंट-अभिव्यक्ति।अन्यथा, e परिभाषित किया गया है के रूप में अगर द्वारा

विशेषता-विनिर्देशक-सेक ऑप्टडीईसीएल-विनिर्देशक-सेकरेफरी-क्वालीफायर ऑप्टeप्रारंभकर्ता;

जहां घोषणा एक समारोह घोषणा और declarator-आईडी इसी संरचित बाध्यकारी घोषणा से लिया जाता है के अलावा अन्य घोषणा के कुछ हिस्सों के रूप में व्याख्या कभी नहीं किया गया है।

नाम तो या तो e के तत्वों या संदर्भ e पर get बुला का परिणाम के लिए बाध्य के लिए उपनाम होने के लिए परिभाषित कर रहे हैं।

अपने उदाहरण में, यह के रूप में यदि द्वारा (यह मानते हुए कि f एक दो तत्व std::tuple रिटर्न) है: (। कि decltype(a) सिवाय और decltype(b) विशेष उपचार उनके referenceness को छिपाने के लिए हो जाता है)

const auto& e = f(); // 1 
using E = remove_reference_t<decltype((e))>; 
std::tuple_element<0, E>::type& a = get<0>(e); 
std::tuple_element<1, E>::type& b = get<1>(e); 

यह स्पष्ट होना चाहिए कि रेखा # 1 f के वापसी मूल्य का जीवनकाल बढ़ाती है।

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