2012-07-17 7 views
6

सी ++ 11 मानक का कहना है (या कम से कम, संस्करण मेरे पास है - नहीं अंतिम एक):अंतर्निहित "लैम्ब्डा पॉइंटर रूपांतरण फ़ंक्शन करने के लिए" स्थिर सदस्यों के "संदर्भ द्वारा" कैप्चर को क्यों रोकता है?

कोई लैम्ब्डा कब्जा के साथ एक लैम्ब्डा अभिव्यक्ति के लिए बंद करने के प्रकार एक सार्वजनिक है गैर आभासी गैर स्पष्ट स्थिरांक रूपांतरण समारोह सूचक के लिए एक ही पैरामीटर होने से कार्य और बंद प्रकार के समारोह कॉल ऑपरेटर के रूप में प्रकार के वापस जाने के लिए।

मुझे समझ में आता है कि एक राज्यव्यापी लैम्ब्डा से फ़ंक्शन पॉइंटर प्राप्त करना क्यों संभव नहीं है क्योंकि फ़ंक्शन पॉइंटर अपने आप से कोई डेटा नहीं रख सकता है।

लेकिन जब कब्जा कर लिया वस्तुओं सिर्फ एक स्थिर सदस्यों/स्थिर चर हैं, वहाँ ऐसी कोई सीमा के बाद से कब्जा कर लिया वस्तुओं के लिए संदर्भ समारोह अपने आप में hardwired किया जा सकता है।

struct A { 
    static int count = 0; 
    void foo() { 
     static int bar = 0; 
     auto fun = [&]()->void { 
      count++; 
      bar++; 
     }; 
     void(*ptrFun)(); 
     ptrFun = fun; // forbidden by the quoted wording 
    } 
}; 

क्यों नहीं यह हमेशा संभव जैसे ही पूर्व राज्यविहीन है एक समारोह सूचक के लिए एक लैम्ब्डा कन्वर्ट करने के लिए है? क्या मुझे कुछ याद आ रहा है या क्या समिति इस विशिष्ट बिंदु को भूल गई है?

+1

मैं एक अनुमान है कि यह कुछ भी क्या कब्जा कर लिया जा रहा है के बारे में ज्यादा साबित करने के लिए सक्षम होने के लिए compilers की आवश्यकता होती है से बचने के लिए है काफ़ी होगा। – Flexo

+0

संकलक के रूप में वे उपयोग किया जाता है (का उपयोग कर स्वत: [और]) पहले से ही स्वचालित रूप से जैसे ही चर पर कब्जा करने में सक्षम है, तो यह एक बहुत अधिक काम शामिल अगर वे स्थिर सदस्यों या वैश्विक हैं, क्योंकि वे जरूरी है की जाँच करने के नहीं होंगे पहले घोषित किया गया था। –

+0

असल में मैंने किसी भी कंपाइलर पर इसका परीक्षण नहीं किया है (मेरे पास केवल एमएसवीसी 10 है जो फ़ंक्शन पॉइंटर रूपांतरण का समर्थन नहीं करता है)। मुझे लगता है कि यह एक जीसीसी विस्तार है? वैसे भी, मेरा सवाल है: मानक द्वारा इसकी अनुमति है (शायद मुझे कुछ याद आया)? यदि नहीं, तो यह क्यों मना किया गया है (शायद एक तकनीकी सीमा है जिसके बारे में मुझे पता नहीं है)? –

उत्तर

9

A::count सब पर कब्जा किया जा की जरूरत नहीं है। केवल this और स्थानीय चर को पकड़ने की आवश्यकता है। स्थिर भंडारण अवधि के साथ चर (उदा।, स्थिर डेटा सदस्य, नामस्थान-स्कोप चर, या फ़ंक्शन-स्थानीय स्थैतिक चर) को कैप्चर करने की आवश्यकता नहीं है क्योंकि वे "अद्वितीय" हैं। प्रत्येक ऐसे चर के बिल्कुल एक उदाहरण है, इसलिए ऑब्जेक्ट के संदर्भ को कैप्चर करने की आवश्यकता नहीं है।

आप अपने लैम्ब्डा से डिफ़ॉल्ट कब्जा निकालते हैं (जैसे कि, [] करने के लिए [&] बदल) और count परिभाषित करते हैं, यह बिना किसी त्रुटि के संकलन चाहिए। (मैं सत्यापित किया है कि दोनों विजुअल C++ 2012 आर सी और जी ++ 4.5.1 कोड स्वीकार केवल परिवर्तन मैं करना था count की इनलाइन प्रारंभ स्थानांतरित करने के लिए किया गया था, उन compilers के न अभी तक का समर्थन करता है के बाद से कि सी ++ 11 सुविधा।)

+0

हां बिल्कुल ... मैं अब बेवकूफ महसूस कर रहा हूं :) लेकिन, अगर हम एक स्थैतिक स्थानीय चर को कैप्चर करना चाहते हैं तो क्या होगा? –

+0

उन्हें भी उसी कारण से कब्जा करने की आवश्यकता नहीं है, प्रत्येक स्थिर स्थानीय चर "अद्वितीय" है और इसका एक ज्ञात पता है। मैंने "स्थिर भंडारण अवधि वाले चर" को संदर्भित करने के उत्तर में संशोधन किया है। यहां अभी भी कुछ सूक्ष्मताएं हो सकती हैं, हालांकि इनमें से कोई भी मुझे अवगत नहीं है (और वीसी 11 और जी ++ 4.5.1 दोनों प्रोग्राम को 'काउंटर' के साथ नामस्थान-स्कोप चर, एक स्थिर डेटा सदस्य, या फ़ंक्शन- स्थानीय स्थैतिक)। –

+0

मुझे नहीं पता था कि इसकी अनुमति थी, धन्यवाद! –

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

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