2013-08-28 4 views
27

मैं इस कोड है:लैम्ब्डा अभिव्यक्ति में कैप्चर वैरिएबल निर्दिष्ट करने का उद्देश्य क्या है?

int i = 0; 
[&i](){i++;}(); 

लेकिन मैं मैं छोड़ सकते हैं और बस का उपयोग करें:

[&](){i++;}(); 

&i निर्दिष्ट करने के उद्देश्य क्या है? (और इसी तरह =var और =)। क्या यह संकलन समय या रनटाइम प्रदर्शन को प्रभावित कर रहा है?

उत्तर

26

&i का मतलब है केवल i संदर्भ के रूप में कब्जा कर लिया गया है, जबकि & का अर्थ है लैम्बडा में उपयोग किए जाने वाले सभी चर, दायरे से कब्जा कर लिया जाता है।

int i = 0, j = 10; 

[&i]{ i++; j++;}(); //error: j is not captured by reference 

[&]{ i++; j++;}(); //ok: both variables are captured by reference 

&i दृष्टिकोण सीमा पर कब्जा कर लिया चर की राशि के लिए भाषा द्वारा प्रदान की जाती है। सी ++ आपको कैप्चर किए गए चर पर पूर्ण नियंत्रण प्रदान करता है, जिसके लिए कैप्चर करने के लिए विशिष्ट चर, कैप्चर करने के लिए (मूल्य या संदर्भ के अनुसार)।

i और = के साथ भी यही तर्क:

int i = 0, j = 10; 

[i]{ i++; j++;}(); //error: j is not captured (only i is captured by value) 

[=]{ i++; j++;}(); //ok: both variables are captured by value 

//more 
[&i, j]{ i++; j++;}(); //ok: captured i by reference, j by value 

आशा है कि मदद करता है।

+2

हाँ मेरा प्रश्न उनके अंतर के बारे में नहीं है, जिसे मैं पहले से ही जानता हूं। मैं जानना चाहता हूं कि पहला क्यों प्रदान किया जाता है यदि दूसरा व्यक्ति पहले से ही – texasbruce

+2

कैप्चर करता है तो दायरे में सब कुछ कैप्चर नहीं किया जाता है। केवल चीजें जो लैम्ब्डा के अंदर उपयोग की जाती हैं। –

+0

@ टिमोथी शील्ड्स: सही। संपादित। धन्यवाद। – Nawaz

17

यह सुविधा निष्पादन और रखरखाव के बारे में प्रदर्शन के बारे में नहीं है। जब आप कंबल कैप्चर सिंटैक्स [&] या [=] का उपयोग करते हैं तो यह मूल विधि और लैम्ब्डा बॉडी के बीच साझा की जाने वाली स्थिति को अस्पष्ट करता है। यह किसी विधि में रखरखाव के मुद्दों में योगदान दे सकता है यदि कोई देव गलत मान लेता है तो वह कैप्चर नहीं होता है और यह है। एक कैप्चर क्लॉज होने से यह अधिक स्पष्ट हो जाता है कि लैम्ब्डा किस राज्य पर निर्भर करता है।

11

& निर्दिष्ट करने का उद्देश्य क्या है? (और इसी तरह = var और =)। क्या यह संकलन समय या रनटाइम प्रदर्शन को प्रभावित कर रहा है?

आप निर्दिष्ट कर सकते हैं कि मूल्य संदर्भ या मूल्य से कैप्चर किए गए हैं या नहीं। [&] का उपयोग करना यह बताता है कि आप संदर्भ द्वारा सब कुछ पर कब्जा करना चाहते हैं, लेकिन आप भी लैम्ब्डा लिख ​​सकते हैं जो करता है:

[=, &i, &j]() 

कौन सा छोड़कर कब्जा i और j संदर्भ द्वारा मूल्य से सब कुछ, पर कब्जा कहते हैं।

अपने विशिष्ट मामले में, यह उपयोगी नहीं है - आप केवल संदर्भ के अनुसार सबकुछ कैप्चर कर सकते हैं, और संकलक यह निर्धारित करेगा कि आप i का उपयोग कर रहे हैं, और संदर्भ द्वारा इसे कैप्चर कर रहे हैं - लेकिन जब आप एकाधिक चर के साथ सौदा करते हैं कब्जा कर लिया, सी ++ आपको यह नियंत्रित करने की अनुमति देता है कि प्रत्येक व्यक्ति को अलग-अलग कैप्चर किया जाता है।

4

यदि आप कैप्चर करने के लिए चर सूचीबद्ध करते हैं, तो आप जो चाहते हैं उसमें स्पष्ट हो रहे हैं। और यदि आप ऐसा कुछ उपयोग करते हैं जिसे आप नहीं चाहते थे तो आपको एक कंपाइलर त्रुटि मिलती है (आपने इसे कैप्चर नहीं किया था)। यह एक अच्छी बात हो सकती है (आपने कार्यान्वयन में वास्तविक गलती की है) या एक बुरी चीज (आप चर को सूचीबद्ध करना भूल गए हैं)।

यह वास्तव में विशेष परिदृश्य पर निर्भर करता है।मैं यह चाहता हूं कि लैम्ब्डा और/या अधिक जटिल क्षेत्र शामिल है, जितना बेहतर होगा कि आप कैप्चर करने के बारे में स्पष्ट हों।

एक अतिरिक्त बिंदु है, और यह संदर्भ द्वारा कैप्चरिंग और संदर्भ द्वारा कैप्चर कर रहा है - आपको उनमें से कम से कम एक में स्पष्ट होना चाहिए। उदाहरण:

int i, j, k; 

auto f = [=, &i]() { /* code which can read i, j and k but can only modify i */ }; 
21

कभी-कभी आप अलग अलग तरीकों से अलग चर पर कब्जा कर सकते हैं:

std::vector<int> v { 7, 8, 9, 10, 11 }; 
int n = 3; 

//Capture v by reference and n by value: 
auto getNth = [&v, n](){ return v[n]; }; 

//Behavior: 
n = 9999; 
getNth(); //returns 10 - changing n didn't affect the lambda 
v[3] = 42; 
getNth(); //returns 42 - changing v did affect the lambda 

यही कारण है कि अधिक-विस्तृत वाक्य रचना उपलब्ध है।

+1

+1 यह उत्तर है। – Mehrdad

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