मैं सी ++ 11 में कुछ नई सुविधाओं के साथ खेल रहा हूं, और मैंने निम्नलिखित प्रोग्राम लिखने की कोशिश की, उम्मीद है कि यह काम न करे। मेरे आश्चर्य करने के लिए बहुत है, यह (जीसीसी 4.6.1 पर लिनक्स 86 पर 'एसटीडी = C++ 0x' ध्वज के साथ) करता है:सी ++ लैम्ब्डास, कैप्चरिंग, स्मार्ट पटर, और स्टैक: यह क्यों काम करता है?
#include <functional>
#include <iostream>
#include <memory>
std::function<int()> count_up_in_2s(const int from) {
std::shared_ptr<int> from_ref(new int(from));
return [from_ref]() { return *from_ref += 2; };
}
int main() {
auto iter_1 = count_up_in_2s(5);
auto iter_2 = count_up_in_2s(10);
for (size_t i = 1; i <= 10; i++)
std::cout << iter_1() << '\t' << iter_2() << '\n'
;
}
मैं उम्मीद कर रहा था 'from_ref' हटाए जाने के लिए जब से प्रत्येक निष्पादन लौम्बा रन लौटा यहां मेरा तर्क है: एक बार count_up_in_2s चलाया जाता है, तो_ref को स्टैक से पॉप किया जाता है, फिर भी क्योंकि लौटा हुआ लैम्ब्डा सीधे भाग नहीं जाता है, क्योंकि यह वापस आ गया है, एक संक्षिप्त अवधि के लिए अस्तित्व में एक और संदर्भ नहीं है जब तक कि एक ही संदर्भ न हो जब लैम्ब्डा वास्तव में चलाया जाता है तब वापस धक्का दिया जाता है, इसलिए साझा_ptr की संदर्भ संख्या शून्य हिट नहीं होनी चाहिए और फिर डेटा को हटा देना चाहिए?
जब तक सी ++ 11 का लैम्ब्डा कैप्चरिंग एक बड़ा सौदा नहीं है, तो मैं इसे क्रेडिट दे रहा हूं, अगर यह है, तो मैं प्रसन्न हूं। यदि यह मामला है, तो क्या मैं मान सकता हूं कि सी ++ 11 का परिवर्तनीय कैप्चरिंग सभी लेक्सिकल स्कोपिंग/क्लोजर ट्रिकरी को ला लिस्प को तब तक अनुमति देगी जब तक कि कुछ/गतिशील रूप से आवंटित स्मृति की देखभाल कर रहा हो? क्या मैं मान सकता हूं कि सभी कब्जे वाले संदर्भ तब तक जीवित रहेगा जब तक कि लैम्ब्डा स्वयं हटा नहीं जाता है, जिससे मुझे उपरोक्त फैशन में smart_ptrs का उपयोग करने की इजाजत मिलती है?
यदि ऐसा लगता है कि यह है, तो इसका मतलब यह नहीं है कि सी ++ 11 अभिव्यक्तिपूर्ण उच्च-आदेश प्रोग्रामिंग की अनुमति देता है? यदि ऐसा है, तो मुझे लगता है कि सी ++ 11 समिति ने एक उत्कृष्ट नौकरी की है =)
तो मैं सही समझ में हूँ कि std :: समारोह वस्तु ही उदाहरण की अवधि के दौरान कैप्चर मान संग्रहीत कर लेता साथ स्थानापन्न
? और यह इस संदर्भ को संग्रहीत करके, shared_ptr संदर्भ गणना 0 हिट नहीं करती है? ओह समझा। कितना सुरुचिपूर्ण – Louis
@ लुइस नो, 'फ़ंक्शन' ऑब्जेक्ट नहीं, लेकिन लैम्ब्डा। 'std :: function' lambdas के कैप्चर के बारे में नहीं जानता है। –
तो संदर्भ के कैप्चरिंग और स्टोरेज को std :: function instance में किसी सदस्य के रूप में संग्रहीत करने के बजाय एक विशेष मामले के रूप में संभाला जाता है। धन्यवाद। – Louis