क्या c ++ 11 लैम्ब्डा वे वैरिएबल कैप्चर करते हैं जिनका वे उपयोग नहीं करते हैं?


124

जब मैं [=]यह इंगित करने के लिए उपयोग करता हूं कि मैं चाहूंगा कि सभी स्थानीय चर एक लंबोदर में मूल्य से कब्जा कर लिया जाए, तो क्या इसका परिणाम होगा कि समारोह में सभी स्थानीय चर कॉपी किए जा रहे हैं, या सिर्फ सभी स्थानीय चर जो लंबो द्वारा उपयोग किए जाते हैं ?

इसलिए, उदाहरण के लिए, अगर मेरे पास है:

vector<int> my_huge_vector(100000);
int my_measly_int;
some_function([=](int i){ return my_measly_int + i; });

My_huge_vector की प्रतिलिपि बनाई जाएगी, भले ही मैं इसे लैम्ब्डा में उपयोग नहीं करता हूं?

जवाबों:


115

प्रत्येक चर को स्पष्ट रूप से कैप्चर सूची में नाम दिया गया है। डिफ़ॉल्ट कैप्चर केवल वैरिएबल को कैप्चर करेगा जो दोनों हैं (ए) स्पष्ट रूप से कैप्चर सूची में नाम नहीं हैं और (बी) लैम्ब्डा अभिव्यक्ति के शरीर में उपयोग किया जाता है। यदि एक चर को स्पष्ट रूप से नाम नहीं दिया गया है और आप लंबर अभिव्यक्ति में चर का उपयोग नहीं करते हैं, तो चर पर कब्जा नहीं किया गया है। आपके उदाहरण में, my_huge_vectorकैप्चर नहीं किया गया है।

प्रति C ++ 11 C5.1.2 [expr.prim.lambda] / 11:

यदि एक लैम्ब्डा-एक्सप्रेशन में एक संबद्ध कैप्चर-डिफॉल्ट होता है और इसका कंपाउंड-स्टेटमेंट ओआरआर-यूसेज this या एक वैरिएबल होता है जिसमें ऑटोमैटिक स्टोरेज अवधि होती है और ओआरआर-यूज्ड एंटिटी को स्पष्ट रूप से कैप्चर नहीं किया जाता है, तो ओआरआर-यूज्ड एंटिटी को निहित कैप्चर कहा जाता है।

आपकी लैम्ब्डा अभिव्यक्ति में एक संबद्ध कैप्चर डिफ़ॉल्ट है: डिफ़ॉल्ट रूप से, आप चर का उपयोग करके मूल्य पर कब्जा कर लेते हैं [=]

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

Continue5.1.2 / 14 के साथ जारी रखने के लिए

एक इकाई को प्रतिलिपि द्वारा कैप्चर किया जाता है यदि

  • यह अंतर्निहित रूप से कैप्चर किया गया है और कैप्चर-डिफ़ॉल्ट है =या यदि
  • यह स्पष्ट रूप से एक कैप्चर के साथ लिया गया है जिसमें ए शामिल नहीं है &

चूँकि आपके my_huge_vectorद्वारा अंतर्निहित रूप से कब्जा नहीं किया गया है और यह स्पष्ट रूप से कब्जा नहीं किया गया है, इसलिए इसे कॉपी या संदर्भ द्वारा बिल्कुल भी कब्जा नहीं किया गया है।


10
क्या आप एक पवित्र उद्धरण है?
GManNickG

मैं कहूंगा, हालांकि, .25.1.2 की संपूर्णता सभी विवरणों को समझने के लिए महत्वपूर्ण है। उस खंड में बहुत सारी तकनीकी शब्द परिभाषित हैं और क्योंकि लंबोदर अभिव्यक्ति के विभिन्न घटकों की परिभाषाएं आवश्यक रूप से उलझी हुई हैं, इसलिए छोटे उद्धरणों को बाहर निकालना मुश्किल है जो निश्चित रूप से कहते हैं "यह एक्स है और यही कारण है कि एक्स।"
जेम्स मैकनेलिस

यहां आपका ध्यान आकर्षित करना , जो कहता है कि इस तरह के अनुकूलन की अनुमति नहीं है, कम से कम स्पष्ट रूप से नामित चर के लिए। मुझे यकीन नहीं है कि रेखा कहाँ खींचना है।
GManNickG

@GManNickG: यह कुछ शक्तिशाली अच्छा ट्रोलिंग ;-) है। इससे पहले कि मैं वास्तव में इस पृष्ठ को इंगित करता था, यह महसूस करने से पहले मुझे उस लिंक के तीन अच्छे क्लिक्स मिले ...: -O [किसी भी मामले में, मैं कल सुबह जब मैं कार्यालय में पहुंचता हूं और अद्यतन करता हूं तो मैं भाषा की कल्पना फिर से पढ़ूंगा। उत्तर उचित रूप से।]
जेम्स मैकनेलिस

ओ बकवास, सॉरी !!! मेरे सवाल का जवाब दिया गया था, मेरा मतलब यहां लिंक करने से था। वह भयानक रूप से भ्रमित कर रहा होगा।
GMANNICKG

16

नहीं, my_huge_vectorकब्जा नहीं किया जाएगा। [=]इसका मतलब है कि सभी इस्तेमाल किए गए चर लैम्ब्डा में कैप्चर किए जाते हैं।


6
हां। ध्यान दें कि इस्तेमाल किया गया एक तकनीकी शब्द है, हालांकि, और वास्तव में इसका मतलब है एक परिभाषा नियम का उपयोग किया जाता है । इसलिए, उदाहरण के लिए, विचार करें void f() { const int size(10); [] { int x[size]; }; }। यहाँ, sizeपर कब्जा नहीं है , लेकिन यह ठीक है क्योंकि इसका उपयोग ODR अर्थों में नहीं किया गया है। (विजुअल C ++ 2010 इस कोड को स्वीकार नहीं करता है, क्योंकि VC10 के रिलीज़ होने के बाद या बग के कारण कल्पना बदल गई है, संभवतः इसे आगामी संस्करण में तय किया जाएगा; जी ++ 4.5.1 इसे स्वीकार करता है।)
जेम्स मैकनेलिस

@JamesMcNellis चिंता मत करो, MSVC आज भी बदबूदार बकवास का ढेर है। सीएफ godbolt.org/z/vHnnCX (lulz के लिए gcc में जांच करें)। ने कहा कि; मुझे समझ में नहीं आता है कि मूल्यांकन किए गए अभिव्यक्ति में दिखाई देने वाला कोई भी पहचानकर्ता ओडीआर-उपयोग क्यों नहीं किया जाएगा। मुझे लगता है कि यह मामला निश्चित रूप से ओडीआर-उपयोग है जब तक कि इसका मतलब यह नहीं है कि इसे एक बाधा के रूप में रखा जा सकता है, इस प्रकार केवल मूल्य उपयोगी है? मुझे यकीन नहीं है कि संकलक constसामान संभावित रूप से उत्परिवर्तित नहीं करता है। जब तक शायद सुपर आक्रामक अनुकूलन ध्वज ओएक्स या सामान न हो।
v.oddou
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.