2010-09-15 12 views
8

द्वारा सदस्य चर को कैप्चर करें C++ 11 लैम्ब्डा अभिव्यक्तियों का उपयोग करते समय मैं मूल्य द्वारा सदस्य चर को कैसे पकड़ूं?मूल्य

[my_member] वाक्य रचना का उपयोग करते हुए काम करने के लिए नहीं लगता है, और अंतर्निहित कब्जा this सूचक का उपयोग करता है। कैप्चर प्रकार के सदस्य चर को स्पष्ट रूप से निर्दिष्ट करने का एक तरीका क्या है। क्या यह संभव है? अब के लिए

मेरे वैकल्पिक हल है:

void member_function() 
{ 
    std::shared_ptr<my_member_class> my_member_copy = my_member; // this shouldn't be necessary 
    std::async([=]{ std::cout << *my_member_copy; }); 
    // std::async([=]{ std::cout << *my_member_; }); // wrong, my member could be potentially out of scope 
} 

उत्तर

7

मुझे नहीं लगता कि आप मूल्य से एक सदस्य पर कब्जा कर सकते हैं, तो आप this पर कब्जा कर सकते हैं लेकिन जब से सदस्य है this का हिस्सा आप एक का उपयोग किया जाएगा साझा सदस्य और एक नया चर नहीं।

जानते हुए भी नहीं हैं कि क्या आपके सदस्य टाइप कुछ इस तरह काम करना चाहिए है:

auto copy = my_member; 
std::async([copy]{ std::cout << copy; }); 

मैं क्यों आप अपने उदाहरण में एक shared_ptr उपयोग कर रहे हैं समझ में नहीं आता, यदि आप मान द्वारा कब्जा करने के लिए निश्चित रूप से shared_ptr है चाहता हूँ आखिरी चीज आपको विचार करनी चाहिए।

+0

मुझे साझा_प्टर रेफ गिनती के लिए मूल्यवर्तीकरण के लिए वैल्यू इनऑर्डर द्वारा कैप्चर करने की आवश्यकता है। अन्यथा जब ऑब्जेक्ट ऑब्जेक्ट नष्ट हो जाता है तो वस्तु नष्ट हो जाएगी, इस प्रकार एसिंक ऑपरेशन में संभावित पहुंच उल्लंघन हो सकता है। (लैम्ब्डा में * जोड़ने के लिए भूल गए)। मुझे नहीं लगता कि आप मेरे उदाहरण से अलग कैसे हैं। – ronag

+0

"यह नहीं जानना कि आपका सदस्य किस तरह का काम कर रहा है:", कारण मैंने लिखा है कि ऑटो के बजाय std :: shared_ptr लिखा गया था "my_member" के प्रकार के बारे में स्पष्ट होना चाहिए, जो shared_ptr है। – ronag

-1

अभी, मैं एक ही समस्या का सामना करना पड़ा है और यह अपने आप हल:

  1. कब्जा this सूचक।

है,

std::async([this]{ std::cout << this->my_member_; }); 
//   ^^^^    ^^^^^^ use this syntax 
//   | 
//   ^
//   capture `this` as well 

यह मेरे लिए काम करता है:

  • तो लैम्ब्डा के अंदर this->member वाक्य रचना लिखें। मुझे उम्मीद है कि यह आपके लिए भी काम करना चाहिए। हालांकि, मैं इस ज्ञान से पूरी तरह संतुष्ट नहीं हूं। मेरे काम के बाद, मैं इस कारण को देख सकता हूं कि यह वाक्यविन्यास क्यों आवश्यक है, या यह एक कंपाइलर बग है। मैं GCC 4.5.0 (मिनजीडब्लू) का उपयोग कर रहा हूं।

    ठीक है, मुझे निम्न विषय मिला है जो कक्षा के सदस्य का उपयोग करने के लिए this पॉइंटर को पकड़ा जाना चाहिए।

  • +4

    लेकिन यह "यह" वास्तविक सदस्य चर नहीं है, इसलिए यदि "यह" हटा दिया गया है तो यह अपरिभाषित व्यवहार का कारण बन जाएगा। – ronag

    4

    दुर्भाग्य से, मुझे नहीं लगता कि वहाँ यह करने के लिए एक सीधी-सपाट तरीका है, लेकिन मैं तरीके एक अतिरिक्त प्रतिलिपि बनाने के बिना एक सदस्य पर कब्जा करने के एक जोड़े के बारे में सोच सकते हैं।

    पहला विकल्प अपने उदाहरण के समान है लेकिन स्थानीय चर के लिए एक संदर्भ का उपयोग करता है:

    void member_function() 
    { 
        std::shared_ptr<my_member_class> &my_member_ref = my_member; 
        // Copied by the lambda capture 
        std::async([my_member_ref]{ std::cout << *my_member_ref; }); 
    } 
    

    नोट वहाँ कि नहीं कॉपी करने के लिए मूल्य का कारण जीसीसी के पूर्व 4.6.2 संस्करण में एक बग है कि । Capturing reference variable by copy in C++0x lambda देखें।

    एक दूसरा दृष्टिकोण प्रतिलिपि बनाने के लिए उपयोग करने के लिए बाँध होगा:

    void member_function() 
    { 
        // Copied by std::bind 
        std::async(std::bind([](const shared_ptr<my_member_class>& my_member){ 
         std::cout << *my_member; }, my_member)); 
    } 
    

    इस उदाहरण में, बाँध, my_member की अपनी एक प्रतिलिपि कर देगा और इस प्रति तो संदर्भ द्वारा लैम्ब्डा अभिव्यक्ति को दे दिया जाएगा ।

    +0

    आपके उदाहरणों में से कोई भी मेरे उदाहरण से भिन्न नहीं है। – ronag

    +3

    @ronag मेरे उदाहरणों और आपके कामकाज के बीच महत्वपूर्ण अंतर यह है कि मेरे उदाहरण 'my_member' की एक अतिरिक्त प्रति नहीं बनाते हैं। मेरा पहला उदाहरण केवल सदस्य को स्थानीय संदर्भ में जोड़ता है, जिससे इसे पहली बार कॉपी किए बिना लैम्ब्डा कैप्चर में मूल्य से कैप्चर किया जा सकता है। मेरा दूसरा उदाहरण लैम्बडा कैप्चर की बजाय मूल्य से 'my_member' को कैप्चर करने के लिए बाध्य का उपयोग करके, एक स्थानीय चर का उपयोग करने की आवश्यकता से बचने का एक तरीका था। – rkjnsn

    +0

    @ronag: rkjnsn सही है, उसका उदाहरण 'my_member_copy' बनाते समय वृद्धि/कमी/सूचक-प्रति सहेजता है और इस प्रकार तेज़ होना चाहिए। आप उसका जवाब क्यों कम कर देंगे? – marton78

    2

    के बाद से अपने प्रश्न के बारे में सी ++ 11 है यह वास्तव में एक जवाब नहीं है, लेकिन सी ++ 14 में आप इस तरह कर सकते हैं:

    void member_function() 
    { 
        std::async([my_member=my_member]{ std::cout << *my_member; }); 
    } 
    

    यह करता है अपने खुद के रूप में एक ही बात "काम चारों ओर "(अगर my_member एक साझा_ptr है)।

    0
    auto& copy = my_member; 
    std::async([copy]{ std::cout << copy; }); 
    

    ऑटो & (ऊपर) भी काम करता है और दो बार की प्रतिलिपि बनाने obviates। यद्यपि यह दृष्टिकोण [इस] को पार करने से अधिक वाक्यविन्यास है, यह वस्तु [इस] बिंदुओं पर निर्भरता को बंद करने में गुजरता है।