2012-09-28 8 views
28

मैं नेट पर बंद होने के बारे में पढ़ रहा था। मैं सोच रहा था कि सी ++ में बंद होने के लिए इन-बिल्ड सुविधा है या कोई तरीका है जिसके द्वारा हम सी ++ में बंद कर सकते हैं?क्या हमारे पास सी ++ में बंद है?

+3

नीचे दिए गए उत्तर के अलावा, संदर्भ पृष्ठ के लिए http://en.cppreference.com/w/cpp/language/lambda भी देखें। –

+0

स्पष्ट रूप से बहुत से लोग अभी भी बंद होने के साथ अज्ञात कार्यों को मिलाते हैं। यह अभी भी मेरे लिए स्पष्ट नहीं है अगर सी ++ 11 वास्तव में बंद करने का समर्थन करता है, या सिर्फ अज्ञात कार्य ("लैम्बडास")। मैं _not_ की अपेक्षा नहीं करता कि सी ++ वास्तविक बंदियों को जावास्क्रिप्ट, पायथन, स्कैला और अन्य में समान रूप से समर्थन देने के लिए, यह बहुत ही आश्चर्यजनक लगेगा। – dividebyzero

+1

खुद को गलत प्रदान करते हुए, हाँ, यह प्रतिलिपि में संदर्भों को प्रतिबिंबित करता है, प्रतिलिपि द्वारा और यहां तक ​​कि संदर्भ के अनुसार, केवल एक ही quirk यह है कि कोई कचरा संग्रह नहीं है ... फिर भी बेहतर समझना चाहेंगे कि सभी अभ्यास में कैसे काम करता है http: // en.cppreference.com/w/cpp/language/lambda – dividebyzero

उत्तर

6

हाँ, सी ++ 11 बंद है lambdas नाम दिया है।

सी ++ 03 में लैम्बडास के लिए कोई अंतर्निहित समर्थन नहीं है, लेकिन Boost.Lambda कार्यान्वयन है।

5

मुझे संदेह है कि यह बंद होने से आपके मतलब पर निर्भर करता है। जिसका मतलब है कि मेरे पास है जिसका उपयोग हमेशा किसी प्रकार के कचरा संग्रह का तात्पर्य है (हालांकि मुझे लगता है कि यह संदर्भ गणना का उपयोग करके कार्यान्वित किया जा सकता है); अन्य भाषाओं में लैम्ब्डा के विपरीत, जो संदर्भों को कैप्चर करते हैं और संदर्भित ऑब्जेक्ट जीवित रखते हैं, सी ++ लैम्बडास या तो एक मूल्य कैप्चर करते हैं, या ऑब्जेक्ट को जीवित नहीं रखा जाता है (और संदर्भ आसानी से लटक सकता है)।

12

आप एक समारोह एक एम्बेडेड,, लगातार छिपे रहते हैं और unseparable संदर्भ (स्मृति, राज्य) है कि करने के लिए एक संदर्भ के रूप में बंद है, हाँ से समझते हैं:

class add_offset { 
private: 
    int offset; 
public: 
    add_offset(int _offset) : offset(_offset) {} 
    int operator() (int x) { return x + offset; } 
} 

// make a closure 
add_offset my_add_3_closure(3); 

// use cloure 
int x = 4; 
int y = my_add_3_closure(x); 
std::cout << y << std::endl; 

अगले एक अपने राज्य को संशोधित करता है:

class summer 
{ 
private: 
    int sum; 
public: 
    summer() : sum(0) {} 
    int operator() (int x) { return sum += x; } 
} 

// make a closure 
summer adder; 
// use closure 
adder(3); 
adder(4); 
std::cout << adder(0) << std::endl; 

आंतरिक राज्य को बाहर से संदर्भित (एक्सेस किया जा सकता है) नहीं किया जा सकता है।

इस पर निर्भर करते हुए कि आप इसे कैसे परिभाषित करते हैं, एक बंद में एक से अधिक फ़ंक्शन का संदर्भ हो सकता है या दो बंद एक ही संदर्भ साझा कर सकते हैं, यानी दो कार्य एक ही निरंतर, ..., राज्य साझा कर सकते हैं।

क्लोजर का मतलब है कि मुफ्त चर शामिल नहीं है - यह केवल एक निजी गुण और केवल सार्वजनिक विधि वाले वर्ग के साथ तुलनीय है।

+3

व्यवहार बंद होने के समान है लेकिन मैं नहीं कहूंगा कि यह है एक बंद – Setepenre

+0

@Stepenre क्या अंतर होगा? – Zrin

+2

यह शायद ही एक बंद की तरह दिखता है, क्या तुम यहाँ है तथ्य यह है "ऑपरेटर()" के बजाय किसी अन्य विधि यह है की वजह से सिर्फ एक वस्तु एक राज्य के लिए एक विधि के द्वारा संशोधित किया, प्लस कुछ वाक्यात्मक चीनी पकड़े है। इसे एक लैम्ब्डा वापस करें जो राज्य पर निर्भर करता है, या विधि के पैरामीटर पर, और फिर हम बात कर रहे हैं। – dividebyzero

6

हां, यह दिखाता है कि आप एक मजेदार के बिना राज्य के साथ एक समारोह को कैसे कार्यान्वित कर सकते हैं।

#include <iostream> 
#include <functional> 


std::function<int()> make_my_closure(int x){ 
    return [x]() mutable { 
     ++x; 
     return x; 
    }; 
} 

int main() 
{ 
    auto my_f = make_my_closure(10); 

    std::cout << my_f() << std::endl; // 11 
    std::cout << my_f() << std::endl; // 12 
    std::cout << my_f() << std::endl; // 13 

    auto my_f1 = make_my_closure(1); 

    std::cout << my_f1() << std::endl; // 2 
    std::cout << my_f1() << std::endl; // 3 
    std::cout << my_f1() << std::endl; // 4 

    std::cout << my_f() << std::endl; // 14 
} 

मैं परिवर्तनशील कीवर्ड जो एक अपरिभाषित व्यवहार शुरू की (बजना संस्करण एक कचरा मूल्य लौट रहा था) भूल गया। लागू होने के बाद, बंद करने के लिए ठीक काम करता है (जीसीसी और क्लैंग पर)

+0

वास्तव में सुनिश्चित होने के लिए, यह देखना अच्छा होगा कि क्या होता है यदि आप 'my_f1()' के बाद फिर से 'my_f() 'चलाते हैं, क्योंकि यह अभी भी वही चर हो सकता है जिसे आपने सीधे कॉल के साथ' make_my_closure ' '। – dividebyzero

+1

'' x' make_my_closure' में एक अस्थायी मूल्य है। तो आईएमओ यह समझ में नहीं आता है। मैंने आपके द्वारा पूछे गए मामले को जोड़ा। जो अपेक्षा के अनुसार व्यवहार करता है – Setepenre