2012-09-23 11 views
10

मैंने सोचा था कि संदर्भ केवल संदर्भ के ही जीवन भर के लिए temporaries के जीवन का विस्तार, लेकिन यह स्निपेट के उत्पादन में विरोधाभासी लगता है:एक संदर्भ पैरामीटर के लिए अस्थायी डिफ़ॉल्ट तर्क का जीवनकाल क्या है?

#include <iostream> 

struct X{ ~X(){ std::cout << "Goodbye, cruel world!\n"; } }; 

X const& f(X const& x = X()){ 
    std::cout << "Inside f()\n"; 
    return x; 
} 

void g(X const& x){ 
    std::cout << "Inside g()\n"; 
} 

int main(){ 
    g(f()); 
} 

Live example. आउटपुट:

Inside f() 
Inside g() 
Goodbye, cruel world! 

तो ऐसा लगता है g() के बाद अस्थायी नष्ट हो गया है ... क्या देता है?

+0

यह सामान्य रूप से अमित्र माना जाता है जब downvoting एक व्याख्या नहीं छोड़ देता है। – Xeo

+0

मेरा अनुमान है कि डाउनवॉटर गलती से डाउनवोट बटन दबाता है जब वे वास्तव में अपवॉट बटन को मारने के लिए चाहते थे (आपके उत्तर के लिए कुल वोट देखकर और प्रश्न इस सिद्धांत का भी समर्थन करता है)। किंतु कौन जानता है! –

+0

@ जेसे: अच्छा सिद्धांत, लेकिन डाउनवोट आने से पहले प्रश्न के मुकाबले उत्तर में अधिक उछाल आया था। :) – Xeo

उत्तर

13

मानक §12.2 [class.temporary] में एक विशेष मामले में यह संभालता है:

p4 दो संदर्भों जिसमें temporaries पूर्ण अभिव्यक्ति के अंत से एक अलग बिंदु पर नष्ट कर रहे हैं कर रहे हैं। [...]

पी 5 दूसरा संदर्भ तब होता है जब कोई संदर्भ अस्थायी रूप से बाध्य होता है। अस्थायी जो संदर्भ बाध्य है या अस्थायी है कि एक subobject संदर्भ बाध्य है संदर्भ के जीवनकाल को छोड़कर के लिए बनी रहती है जो करने के लिए की पूरी वस्तु है:

  • एक समारोह में एक संदर्भ पैरामीटर के लिए एक अस्थायी बाध्य कॉल (5.2.2) पूर्ण अभिव्यक्ति के पूरा होने तक जारी रहता है जिसमें कॉल है।

मानक भी पूर्ण भाव पर एक आसान टिप्पणी और §1.9 [intro.execution] p11 में डिफ़ॉल्ट मानकों के संबंध में उनके subexpressions के मूल्यांकन है:

[नोट: एक पूर्ण के मूल्यांकन अभिव्यक्ति में उप-अभिव्यक्तियों का मूल्यांकन शामिल हो सकता है जो पूर्ण अभिव्यक्ति का स्पष्ट रूप से हिस्सा नहीं हैं। उदाहरण के लिए, का मूल्यांकन करने में शामिल उप-अभिव्यक्तियां डिफ़ॉल्ट तर्क (8.3.6) को अभिव्यक्ति में बनाई जाती हैं जो फ़ंक्शन को कॉल करती है, डिफ़ॉल्ट अभिव्यक्ति को परिभाषित करने वाली अभिव्यक्ति नहीं। -end नोट]

1

दिलचस्प, +1। (मेरा मतलब आपके अच्छे आत्म उत्तर से प्रतिस्पर्धा करने का मतलब नहीं है)। रुचि रखने वाले किसी के लिए बस एक साइड नोट। यदि आप एक समान प्रभाव लेकिन गैर स्थिरांक आप इस कदम अर्थ विज्ञान इस्तेमाल कर सकते हैं अनुमति देता है चाहते हैं:

#include <iostream> 

struct X{ 
    ~X(){ std::cout << "Goodbye, cruel world!\n"; } 
    X(X && x){ std::cout << "moved "; } 
    X(){} 
}; 

X f(X x = X()){ 
    std::cout << "Inside f()\n"; 
    return x; 
} 

void g(X x){ 
    std::cout << "Inside g()\n"; 
} 

int main(){ 
    g(f()); 
} 

Inside f() 
moved Inside g() 
Goodbye, cruel world! 
Goodbye, cruel world! 
+0

आप केवल 'एक्स &&' का उपयोग कर सकते हैं और 'std :: move (x) 'वापस कर सकते हैं। :) – Xeo

+0

@Giovanni आपका बयान गलत नहीं है अगर गलत है। –

+1

@Xeo "वापसी std :: move (x)" इस मामले में टालना चाहिए, अधिक जानकारी देखें जैसे https://stackoverflow.com/questions/14856344/when-should-stdmove-be-used-on-a समारोह-रिटर्न-मूल्य –

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

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