2012-02-07 5 views
7

सी ++ 11 मानक बताता है कि, यदि प्रतिलिपि के लिए शर्तों को पूरा किया जाता है (§12.8/31), कार्यान्वयन return एड स्थानीय लैवल्यू चर और फ़ंक्शन पैरामीटर को पहले एक रावल्यू (चाल) के रूप में मानता है, और यदि ओवरलोड रिज़ॉल्यूशन नहीं होता है विस्तृत के रूप में सफल नहीं होगा, फिर इसे एक लाभा (प्रतिलिपि) के रूप में माना जाएगा।क्या फ़ंक्शन से लौटाए जाने पर भी स्थानीय चर के सदस्य उप-डोमेन स्थानांतरित हो जाएंगे?

§12.8 [class.copy] p32

जब एक प्रतिलिपि आपरेशन के इलिजन के लिए मानदंडों को पूरा कर रहे हैं या तथ्य यह है कि स्रोत ऑब्जेक्ट एक समारोह पैरामीटर, और वस्तु कॉपी किया जा करने के लिए एक से नामित किया गया है है के लिए सेव पूरी की जाएगी प्रतिलिपि के लिए कन्स्ट्रक्टर का चयन करने के लिए लेल्यू, ओवरलोड रिज़ॉल्यूशन पहली बार किया जाता है जैसे ऑब्जेक्ट को एक रावल्यू द्वारा नामित किया गया था। यदि ओवरलोड रिज़ॉल्यूशन विफल रहता है, या यदि चयनित कन्स्ट्रक्टर के पहले पैरामीटर का प्रकार ऑब्जेक्ट के प्रकार (संभावित रूप से सीवी-क्वालिफाइड) के लिए एक रावल्यू संदर्भ नहीं है, तो ऑब्जेक्ट को एक लवल्यू के रूप में देखते हुए ओवरलोड रिज़ॉल्यूशन फिर से किया जाता है। [नोट: इस दो चरण के अधिभार रिज़ॉल्यूशन को निष्पादित किया जाना चाहिए चाहे कॉपी प्रतिलिपि हो। यह कथन को निर्धारित करने के लिए कन्स्ट्रक्टर को निर्धारित करता है, और कॉल का विस्तार होने पर भी चयनित कन्स्ट्रक्टर को सुलभ होना चाहिए। -end नोट]

क्या इसमें सदस्य सबोबजेक्ट भी शामिल हैं? मैं निम्नलिखित स्निपेट के साथ परीक्षण किया:

#include <iostream> 

struct traced{ 
    traced(){ std::cout << "default ctor\n"; } 
    traced(traced const&){ std::cout << "copy ctor\n"; } 
    traced(traced&&){ std::cout << "move ctor\n"; } 
}; 

struct X{ 
    traced t; 
}; 

traced f(){ 
    X x; 
    return x.t; 
} 

int main(){ 
    traced t = f(); 
} 

Live example on Ideone. और न जीसीसी 4.7 टीओटी और न ही बजना 3.1 टीओटी "चाल ctor" है, जो मुझे विश्वास है कि मानक सदस्य subobjects शामिल नहीं है प्रदर्शित करेगा।

क्या मैंने कुछ अनदेखा किया? क्या मेरा टेस्ट कोड टूटा हुआ है? उत्पादन के रूप में वास्तव में क्या कारण बनता है?

+0

मुझे नहीं लगता कि आपके परीक्षण साबित करते हैं कि वे नहीं कर सकते हैं। यह केवल यह दिखा सकता है कि संकलक के लिए यह पुष्टि करना मुश्किल है कि 'elision' के मानदंडों को पूरा किया गया है क्योंकि हाइलाइट किया गया अनुभाग केवल तभी प्रासंगिक है जब संकलक मानदंडों की पुष्टि कर सके। –

+0

मैं थोड़ा उलझन में हूँ। मुझे लगता है कि मैं रिटर्न-वैल्यू-ऑप्टिमाइज़ेशन को मिश्रित कर रहा हूं और एलिशन कॉपी कर रहा हूं। मैंने कोड को थोड़ा छोटा कर दिया और चाल चल गई, [यह डेमो] देखें (http://ideone.com/SQqvH)। मैं आरवीओ की इजाजत देकर सीधे 'एफ()' से एक्स वापस कर देता हूं। और यह 'traced t = f()। T;' का उपयोग करता है जो चाल को दर्शाता है। (मुझे नहीं पता कि यह मदद करता है!) –

+0

@Aaron। आरवीओ प्रतिलिपि elision का सिर्फ एक आवेदन है। :) कहने के लिए एक उचित सबसेट। इसके अलावा, वापसी के बाद पहुंच के साथ अच्छा विचार। अफसोस की बात है, यह मेरे वास्तविक कोड में लागू नहीं है। :/ – Xeo

उत्तर

6

एक उपरोक्त लौटने पर आप इसके निर्माण को दूर नहीं कर सकते हैं। इस बारे में इस बारे में सोचें: उस स्थान पर वस्तु का निर्माण करने के लिए अनिवार्य रूप से राशि को स्थानांतरित करें और कॉपी करें, जिसे अंततः स्थानांतरित किया जाएगा या कॉपी किया जाएगा। यह पूर्ण वस्तुओं के लिए काम करता है क्योंकि उचित स्थान को अलग किया जाएगा। यह subobjects के साथ काम नहीं करता है क्योंकि आप संलग्न वस्तु का निर्माण करेंगे। यहां तक ​​कि यदि इसका उपनिवेश के समान आकार है, यानी पर्याप्त जगह है, संलग्न वस्तु नष्ट हो जाती है और उपनिवेशों को मजेदार चीजें कर सकती है।

प्रभावी रूप से, इसका मतलब है कि विषय का निर्माण elided नहीं किया जा सकता है।

+2

+1 - लेकिन आपको बैठक में ध्यान देना चाहिए! –

+0

बदले में इसका मतलब है कि '§12.8/32' का पूरा अनुच्छेद लागू नहीं होगा। मुझे आश्चर्य है कि मानक यह क्यों नहीं कहता है कि, यदि लौटाया गया ऑब्जेक्ट स्थानीय लवल्यू या बाय-वैल्यू फ़ंक्शन पैरामीटर है, तो इसे स्थानांतरित किया जाना चाहिए, अन्यथा कॉपी किया जाना चाहिए। प्रतिलिपि elision की पात्रता पर भरोसा करने के लिए थोड़ा सख्त लगता है। कोई कारण? – Xeo

+0

@ रिचर्ड: अच्छा है।:) हो सकता है कि आप बैठकों में मेरी टिप्पणी में अंतिम बिंदु ला सकते हैं यदि कोई विशेष तर्कसंगत नहीं है जो इसे मना कर देगा? :) – Xeo

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