c++ एक वर्ग में सदस्य कार्यों के साथ सामान्य std:: फ़ंक्शन ऑब्जेक्ट का उपयोग करना




function function-pointers (3)

एक वर्ग के लिए मैं कुछ फ़ंक्शन पॉइंटर्स को एक ही कक्षा के सदस्य फ़ंक्शंस में std::function ऑब्जेक्ट्स संग्रहीत करना चाहता हूं। लेकिन मैं इस कोड के साथ शुरुआत में ठीक से विफल रहता हूं:

class Foo {
    public:
        void doSomething() {}
        void bindFunction() {
            // ERROR
            std::function<void(void)> f = &Foo::doSomething;
        }
};

मुझे error C2064: term does not evaluate to a function taking 0 arguments प्राप्त error C2064: term does not evaluate to a function taking 0 arguments xxcallobj में error C2064: term does not evaluate to a function taking 0 arguments को error C2064: term does not evaluate to a function taking 0 arguments जिसमें कुछ अजीब टेम्पलेट xxcallobj त्रुटियां होती हैं। वर्तमान में मैं विजुअल स्टूडियो 2010/2011 के साथ विंडोज 8 पर काम कर रहा हूं और वीएस 10 के साथ विन 7 पर भी असफल रहा हूं। त्रुटि कुछ अजीब सी ++ नियमों पर आधारित होना चाहिए जो मैं नहीं मानता।

संपादित करें: मैं बूस्ट का उपयोग नहीं करता हूं। यह एमएस कंपाइलर में एकीकृत सी ++ 11 है।


Answer #1

किसी ऑब्जेक्ट के साथ एक गैर स्थैतिक सदस्य फ़ंक्शन को कॉल किया जाना चाहिए। यही है, यह हमेशा "इस" सूचक को इसके तर्क के रूप में निहित रूप से गुजरता है।

चूंकि आपका std::function हस्ताक्षर निर्दिष्ट करता है कि आपका फ़ंक्शन कोई तर्क नहीं लेता है ( <void(void)> ), आपको पहले (और केवल) तर्क को बाध्य करना होगा।

std::function<void(void)> f = std::bind(&Foo::doSomething, this);

यदि आप पैरामीटर के साथ एक फ़ंक्शन बाध्य करना चाहते हैं, तो आपको प्लेसहोल्डर निर्दिष्ट करना होगा:

using namespace std::placeholders;
std::function<void(int,int)> f = std::bind(&Foo::doSomethingArgs, this, _1, _2);

या, यदि आपका कंपाइलर सी ++ 11 लैम्बडा का समर्थन करता है:

std::function<void(int,int)> f = [=](int a, int b) {
    this->doSomethingArgs(a, b);
}

(मेरे पास अभी एक सी ++ 11 सक्षम कंपाइलर नहीं है, इसलिए मैं इसे जांच नहीं सकता।)


Answer #2

या तो आपको चाहिए

std::function<void(Foo*)> f = &Foo::doSomething;

ताकि आप इसे किसी भी उदाहरण पर कॉल कर सकें, या आपको एक विशिष्ट उदाहरण बांधना होगा, उदाहरण के लिए

std::function<void(void)> f = std::bind(&Foo::doSomething, this);

Answer #3

यदि आपको क्लास इंस्टेंस के बिना सदस्य फ़ंक्शन को स्टोर करने की आवश्यकता है, तो आप ऐसा कुछ कर सकते हैं:

class MyClass
{
public:
    void MemberFunc(int value)
    {
      //do something
    }
};

// Store member function binding
auto callable = std::mem_fn(&MyClass::MemberFunc);

// Call with late supplied 'this'
MyClass myInst;
callable(&myInst, 123);

स्टोरेज प्रकार ऑटो के बिना कैसा दिखता है? कुछ इस तरह:

std::_Mem_fn_wrap<void,void (__cdecl TestA::*)(int),TestA,int> callable

आप इस फ़ंक्शन स्टोरेज को मानक फ़ंक्शन बाइंडिंग में भी पास कर सकते हैं

std::function<void(int)> binding = std::bind(callable, &testA, std::placeholders::_1);
binding(123); // Call

पिछले और भविष्य के नोट्स: एक पुराना इंटरफ़ेस std :: mem_func अस्तित्व में था, लेकिन तब से इसे बहिष्कृत कर दिया गया है। सदस्य प्रस्तावों को पॉइंटर बनाने के लिए सी ++ 17 पोस्ट करने के बाद एक प्रस्ताव मौजूद है। यह सबसे स्वागत है।







tr1