2012-05-10 19 views
5

क्या यह कोड मान्य है?सी ++ अस्थायी परिवर्तनीय जीवनकाल

int foo() 
{ 
    std::vector<std::string>& v = std::vector<std::string>(5, "X"); 

    // Do something silly... 

    return 42; 
} 

किसी कारण मैंने सोचा था कि अस्थायी std::vector वस्तु (सही काम संकेत से) विलुप्त जाना चाहिए कि सही होने के बाद यह निर्माण है के लिए (इस प्रकार संदर्भ अमान्य प्रतिपादन)।

हालांकि, डिबगिंग साबित करता है कि मैं गलत हूं और, ठीक है, मुझे एहसास हुआ कि मुझे समझ में नहीं आता कि फ़ंक्शन रिटर्न होने पर अस्थायी चर को क्यों नष्ट किया जाता है।


मुझे लगता है कि मैं कुछ मौलिक के एक मजबूत गलतफहमी है, तो मुझे प्रबुद्ध कृपया :)

+0

जब आप कहते हैं कि "डिबगिंग साबित करता है कि मैं गलत हूं", तो आपका क्या मतलब है? –

उत्तर

8

कोड आप दिखाया है अवैध – temporaries केवल rvalue संदर्भ या स्थिरांक करने के लिए बाध्य कर सकते हैं lvalue संदर्भ।

वीसी ++ इसे एक एक्सटेंशन के रूप में अनुमति देता है (और a level 4 warning ऐसा कहता है)।

+1

gcc इस बारे में अच्छी तरह से शिकायत करता है: 'त्रुटि: प्रकार के गैर-कॉन्स्ट संदर्भ का अमान्य प्रारंभिक' std :: vector , std :: आवंटक >, std :: आवंटक < std :: basic_string , std :: allocator >>> और 'अस्थायी प्रकार से' std :: vector , std :: आवंटक >, std :: आवंटक , std :: आवंटक >>> – Scottymac

+0

धन्यवाद, उस एक्सटेंशन के बारे में नहीं पता * (और, ठीक है, मैंने 'gcc' की कोशिश की)। * –

+2

@ Yippie-Kai-Yay: तो आपको स्तर 4 चेतावनियों के साथ सक्षम होना चाहिए। ; -] – ildjarn

2

आपके पास एक अस्वीकृत वस्तु का संदर्भ है। यह 'सरासर किस्मत' द्वारा काम करता है (देखें सी ++ प्रोग्रामिंग भाषा, धारा 10.4.10 अस्थायी वस्तुओं)। आप गारंटी नहीं दे सकते कि यह हर कंपाइलर में काम करेगा।

आप केवल यह सुनिश्चित कर सकते हैं कि अस्थायी जीवनकाल const संदर्भ से जुड़ा हुआ है।

+2

यह इस मामले में बेहद भाग्यशाली नहीं है, यह ओपी का उपयोग कर रहे संकलक द्वारा प्रदान किया गया एक भाषा विस्तार है। – ildjarn

+0

@ildjarn मैं सिर्फ स्ट्राउस्ट्रप जीभ-इन-गाल उद्धृत कर रहा हूं। मुद्दा यह है कि यह गैर-पोर्टेबल/गैरकानूनी/अविश्वसनीय है या जिसे आप इसे कॉल करना चाहते हैं। – frozenkoi

+3

यह पोर्टेबल नहीं है, सहमत है, लेकिन यह भी गैरकानूनी नहीं है; सी ++ मानक (§1.4/8) विशेष रूप से भाषा एक्सटेंशन को तब तक अनुमति देता है जब तक विस्तार अच्छी तरह से गठित कोड के व्यवहार को प्रभावित न करे, और संकलक नैदानिक ​​(चेतावनियां गिनती) जारी करता है। – ildjarn

3

अस्थायी का सामान्य जीवनकाल पूर्ण अभिव्यक्ति के अंत तक है, जिसमें इसे बनाया गया है; यह उपयोग पर तुरंत को नष्ट नहीं किया गया है। यदि अस्थायी का उपयोग संदर्भ को प्रारंभ करने के लिए किया जाता है, इसका जीवनकाल संदर्भ के मिलान के लिए बढ़ाया जाता है ( कन्स्ट्रक्टर की प्रारंभकर्ता सूची में अस्थायी रूप से बनाए गए अपवाद के उल्लेखनीय अपवाद के साथ)।

बेशक, आपका कोड अवैध है; यदि संदर्भ गैर-कॉन्स के लिए है, तो यह केवल कुछ प्रकार के अंतराल के साथ प्रारंभ किया जा सकता है। लेकिन अगर यह कानूनी (और कम से कम एक संकलक इसे स्वीकार करता है), तो जीवनकाल संदर्भ के मिलान के लिए बढ़ाया जाना चाहिए।

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