2017-05-17 13 views
5

कैप्चरिंग लैम्बडा लौटने पर आज मुझे सी ++ 11 लैम्बडा में एक बहुत ही अनजान व्यवहार (मेरे लिए, कम से कम) का सामना करना पड़ा। प्रश्न में कोड निम्न है:एक स्थानीय चर

#include <stdio.h> 

auto sum(int x) { 
    return [&x](int y) { 
     return x + y; 
    }; 
} 

int main() { 
    int a = sum(2)(3); 
    printf("%d\n",a); 
} 

प्रिंटिंग के बजाय, यह प्रिंट गिब्बिश। असल में, कम से कम जीसीसी के मेरे संस्करण में, यदि मैं -ओ 2 अनुकूलन ध्वज चालू करता हूं, तो यह वास्तव में प्रिंट करता है 5. चूंकि आउटपुट कंपाइलर के अनुकूलन स्तर पर निर्भर करता है, यह अपरिभाषित व्यवहार है। थोड़ी देर के बाद, मुझे लगता है कि मुझे समझ में आया कि क्या हो रहा है।

जब फ़ंक्शन योग कहा जाता है, तो तर्क x के अनुरूप एक स्टैक वैरिएबल 2 पर सेट होता है, फिर फ़ंक्शन योग रिटर्न होता है, और इस स्टैक वैरिएबल को किसी भी कोड द्वारा अधिलेखित किया जा सकता है जिसे संकलक को निम्नलिखित कोड निष्पादित करने की आवश्यकता होती है , और उस समय तक लैम्ब्डा को अंततः निष्पादित किया जाता है, वह स्थान जहां एक्स अब 2 नहीं था, और प्रोग्राम 3 मनमाने ढंग से पूर्णांक में जोड़ता है।

क्या सी ++ में घुमाने के लिए कोई शानदार तरीका है गारंटी देता है कि चर सही ढंग से कब्जा कर लिया जाता है?

+4

मूल्य '[=] 'द्वारा कैप्चर करें। – Galik

+0

धन्यवाद! यह अपेक्षा की तुलना में आसान तरीका था। –

+2

बस पाठक के लिए, यह सी ++ 14 है, सी ++ 11 नहीं। फ़ंक्शन रिटर्न मानों की कटौती टाइप करें C++ 14 में जोड़ा गया था। – cdhowie

उत्तर

8

int x सीमित जीवनकाल है। स्वचालित स्टोरेज चर के संदर्भ (जिसे आप "स्टैक" कहते हैं) केवल वैरिएबल के जीवनकाल पर मान्य हैं। इस मामले में, केवल स्टैक फ्रेम (दायरा) के अंत तक जहां चर मौजूद है, या फ़ंक्शन तर्क के लिए फ़ंक्शन।

[&] संदर्भ द्वारा किसी भी उल्लिखित ("स्थानीय") चर को कैप्चर करता है, this को छोड़कर (जो उपयोग किए जाने पर या अनुमानित रूप से उपयोग किए जाने पर मूल्य द्वारा कैप्चर किया जाता है)। [=] मूल्य द्वारा किसी भी निर्दिष्ट चर को कैप्चर करता है। [x] स्पष्ट रूप से x पर स्पष्ट रूप से संदर्भित करेगा, और [&x] स्पष्ट रूप से संदर्भित करेगा। सी ++ 17, [*this] में भी काम करता है।

[x=std::move(x)], या [blah=expression] भी है।

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

+0

विस्तृत जवाब के लिए धन्यवाद कुछ के बारे में तर्क करने के लिए इस्तेमाल नहीं किया जा सकता। अधिकांश जवाब मैं सी ++ पर currying शामिल टेम्पलेट कोड का एक बहुत कुछ है कि मुझे समझ में नहीं कर सकता था ऊपर देखा, तो मैं बस सामान की कोशिश कर रहा शुरू कर दिया।अब मैं बेहतर जानता हूं कि मैं क्या कर रहा हूं। –

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