2017-06-25 19 views
8

मैं अपने वर्तमान प्रोजेक्ट में निम्नलिखित (सरलीकृत) कोड है:सी ++ लैम्ब्डा'this' कदम ऑपरेशन के बाद सूचक अमान्यकरण

#include <iostream> 
#include <string> 
#include <functional> 
#include <vector> 


class Test{ 

public: 

    Test() = default; 
    Test(const Test& other) = delete; 
    Test& operator=(const Test& other) = delete; 
    Test(Test&& other) = default; 
    Test& operator=(Test&& other) = default; 



    void setFunction(){ 
     lambda = [this](){ 
      a = 2; 
     }; 
    } 

    int callAndReturn(){ 
     lambda(); 
     return a; 
    } 

private: 
    std::function<void()> lambda; 
    int a = 50; 
}; 


int main() 
{ 
    Test t; 
    t.setFunction(); 
    std::vector<Test> elements; 
    elements.push_back(std::move(t)); 
    std::cout << elements[0].callAndReturn() << std::endl; 
} 

जब मैंने इसे चलाने के लिए, मूल्य 50 अपेक्षित मान 2 के बजाय छपा है। मुझे लगता है कि ऐसा होता है क्योंकि लैम्ब्डा फ़ंक्शन वर्तमान this पॉइंटर को कैप्चर करता है। चालन ऑपरेशन के बाद this पॉइंटर परिवर्तन और फ़ंक्शन गलत a पर लिखता है।

अब मेरी सवाल यह है: नए Test इतना करने के लिए लैम्ब्डा के कब्जा कर लिया संदर्भ बदलने के लिए एक तरीका है कि मान 2 छपा है है?

उत्तर

4

समाधान this पर कब्जा नहीं करना है। इसके बजाय, इसे स्वीकार करने के लिए अपने कब्जे वाले फ़ंक्शन प्रकार को बदलें। और a पर अप्रत्यक्ष पहुंच के लिए सदस्य (मूल्य द्वारा कब्जा कर लिया गया) के लिए एक सूचक का उपयोग करें।

std::function<void(Test*)> lambda; 

void setFunction(){ 
    auto a = &Test::a; 
    lambda = [=](Test *t){ 
     (t->*a) = 2; 
    }; 
} 

int callAndReturn(){ 
    lambda(this); 
    return a; 
} 

Live Example


रूप Galik बताया गया है, यदि आप केवल एक ही हार्ड-कोडेड सदस्य का उपयोग करने की जरूरत है, तो आप भी सदस्य है कि सूचक जरूरत नहीं है। इस प्रकार लैम्ब्डा कैप्चर-कम हो सकता है:

void setFunction(){ 
    lambda = [](Test *t){ 
     t->a = 2; 
    }; 
} 
+2

क्या आप सिर्फ टी-> ए = 2 नहीं कर सकते हैं; और सदस्य सूचक के बारे में भूल जाते हैं? – Galik

+0

@ गैलिक - मुझे नहीं पता क्यों, लेकिन मुझे लगता है कि ओपी चाहता था कि सदस्य हार्डकोड न करें। मैं निश्चित रूप से इसे जोड़ दूंगा, क्योंकि एक कैप्चर-कम लैम्ब्डा जितना आसान है उतना आसान है। – StoryTeller

+0

मुझे लगता है कि मूल समस्या यह है कि लैम्ब्डा कैप्चरिंग 'यह' पॉइंटर है जो * move * के साथ अपडेट नहीं होता है। पैरामीटर के रूप में वर्तमान 'इस' सूचक में गुजरकर लैम्ब्डा हमेशा सही वस्तु पर काम करता है। – Galik

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