2012-04-05 16 views
9

मैं एक अवधारणा और त्रुटि को समझने की कोशिश कर रहा हूं। इसमें क्या गलत है?std :: गैर स्थैतिक सदस्य फ़ंक्शंस के साथ फ़ंक्शन

class A 
{ 
public: 
    A() 
    { 
     std::function<void(int)> testFunc(&A::func); 
    } 

private: 
    void func(int) {} 
} 

मेरे सवाल का, वस्तु के किसी भी प्रकार है कि एक विशिष्ट उदाहरण है जहां std :: समारोह एक सदस्य समारोह सूचक की तरह कार्य करता है, निराला प्रकार परिभाषा के बिना सिवाय के एक सदस्य को फोन करने में सक्षम है बनाने के लिए यह संभव है कि कर सकते हैं वंशानुगत कक्षाओं में फ़ंक्शन पैरामीटर के रूप में उपयोग नहीं किया जाएगा। उदाहरण के लिए:

class A 
{ 
public: 
    A() 
    { 
     index[WM_CREATE] = &A::close; 
     index[WM_DESTROY] = &A::destroy; 
    } 

protected: 
    map<UINT msg, void (A::*)(HWND, UINT , WPARAM, LPARAM)> index; 
    void close(HWND,UINT, WPARAM, LPARAM); 
    void destroy(HWND, UINT, WPARAM, LPARAM); 
}; 

class B : public A 
{ 
public: 
    B() 
    { 
     index[WM_CREATE] = &B::create; // error because it's not a pointer of type A::* 
    } 
private: 
    void create(HWND, UINT, WPARAM, LPARAM); 

}; 

मैं सोच रहा हूँ मैं तो जैसे std :: कार्यों का उपयोग करने का सही रास्ते पर हूं:

class A 
{ 
public:    //   Gigantic stl error with these two 
    A()    //       | 
    {    //       V 
     index[WM_CREATE] = std::function<void(HWND, UINT, WPARAM, LPARAM>(&A::close); 
     index[WM_DESTROY] = std::function<void(HWND, UINT, WPARAM, LPARAM>(&A::destroy); 
    } 

protected: 
    map<UINT msg, std::function<void(HWND, UINT, WPARAM, LPARAM)> > index; 
    void close(HWND,UINT, WPARAM, LPARAM); 
    void destroy(HWND, UINT, WPARAM, LPARAM); 
}; 

class B : public A 
{ 
public:     //    and this one 
    B()     //      | 
    {      //      V 
     index[WM_CREATE] = std::function<void(HWND, UINT, WPARAM, LPARAM)>(&B::create); 
    } 
private: 
    void create(HWND, UINT, WPARAM, LPARAM); 

}; 

अगर किसी को समझा सकता है इन विशाल गुप्त त्रुटियों क्या मतलब है और कैसे करने के लिए उन्हें ठीक करें, मैं इसकी सराहना करता हूं।

+0

जब आप कहते हैं "एक विशिष्ट उदाहरण के सदस्य को कॉल करें जहां 'std :: function' सदस्य फ़ंक्शन पॉइंटर की तरह कार्य करता है", तो इसका मतलब यह है कि विशिष्ट उदाहरण 'std :: function के निर्माण के समय निर्दिष्ट है ऑब्जेक्ट? यह वही है जो 'शून्य (int)' हस्ताक्षर सुझाता है, लेकिन फिर परिणाम ऑब्जेक्ट "सदस्य फ़ंक्शन पॉइंटर की तरह" कार्य नहीं करेगा, यह कॉलबैक/मज़ेदार की तरह कार्य करेगा। यदि दूसरी ओर आप का मतलब है कि परिणामी 'std :: function' ऑब्जेक्ट वास्तव में सदस्य फ़ंक्शन पॉइंटर की तरह कार्य करता है, तो हस्ताक्षर गलत है (उदा। यह 'शून्य (ए और, int)' हो सकता है)। जो यह है? –

+0

यह सुनिश्चित नहीं है कि कॉलबैक/मज़ेदार क्या है, लेकिन यह थोड़े लगता है जैसे हम स्थिर कार्यों और गैर स्थैतिक कार्यों के बीच अंतर कर रहे हैं, और मैं इसे एक गैर स्थैतिक कार्य करना चाहता हूं। वे हैंडलर हैं इसलिए उन्हें केवल इन उदाहरण सदस्यों में हेरफेर करने में सक्षम होना चाहिए। उदाहरणों में, मैं चाहता हूं कि उस फ़ंक्शन को कॉल किया जाए जब संबंधित मैप इंडेक्स पास हो जाए। बस, मैं यह करना चाहता हूं: अनुक्रमणिका [WM_CREATE] (hwnd, msg, lparam, wparam); और एकमात्र तरीका मैं ऐसा करने के लिए सोच सकता हूं कि स्टोर फ़ंक्शन पॉइंटर्स या कुछ ऐसा ही है। मैं वास्तविक पॉइंटर्स नहीं कर सकता क्योंकि यह विरासत तोड़ता है :( – FatalCatharsis

+0

क्या आप ['std :: mem_fun'] (http: //en.cppreference.com/w/cpp/utility/functional/mem_fn) इसके बजाय? –

उत्तर

11

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

std::function<void(int)> testFunc(std::bind(&A::func, this, _1)); 

यह कार्य करने के लिए वर्तमान एक उदाहरण के इस सूचक बांधता है तो यह है:

एक std :: कार्य करने के लिए एक सदस्य समारोह सेट करने के लिए, तो आप इस तरह std :: बाँध उपयोग करने की आवश्यकता फ़ंक्शन पॉइंटर और ऑब्जेक्ट इंस्टेंस, जो फ़ंक्शन को ठीक से कॉल करने के लिए पर्याप्त जानकारी है। _1 तर्क इंगित करता है कि फ़ंक्शन कहलाते समय पहला स्पष्ट तर्क प्रदान किया जाएगा।

+0

त्रुटि C2065: '_1': अविकसित पहचानकर्ता। मैंने इसे 'हैंडलर इंडेक्स [WM_CREATE] = std :: function (std :: bind (& BasicWindow :: MsgCreate, this, _1))' – FatalCatharsis

+0

"के लिए आपको प्लेसहोल्डर की आवश्यकता है प्रत्येक तर्क, तो यह होगा: 'std :: function (std :: bind (& BasicWindow :: msgCreate, this, _1, _2, _3, _4))' –

+0

आह गेटचा, जब मैं थोड़ी देर में घर में हूं तो मैं कोशिश करूंगा। – FatalCatharsis

0

मेरे सवाल का, वस्तु के किसी भी प्रकार है कि केवल जानकारी मौजूद नहीं है कि वास्तव में इस मामले में एक विशिष्ट उदाहरण

के एक सदस्य को फोन करने में सक्षम है बनाने के लिए यह संभव है क्या विशिष्ट उदाहरण std::function ऑब्जेक्ट का उपयोग करना चाहिए: &A::func का उपयोग अपने आप नहीं किया जा सकता है (उदाहरण के लिए (this->*&A::func)(0)&A::func का उपयोग उदाहरण *this) के साथ करता है। प्रयास करें:

std::function<void(int)> testFunc = std::bind(&A::func, this); 

(ध्यान रहे कि std::bind(&A::func, *this) और std::bind(&A::func, this) थोड़ा अलग अर्थ विज्ञान है है।)

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