2013-04-05 9 views
17

मेरी कक्षा में Mat कहा जाता है, मैं एक ऐसा फ़ंक्शन रखना चाहता हूं जो पैरामीटर के रूप में एक और कार्य करता है। अभी मेरे पास नीचे 4 कार्य हैं, लेकिन प्रिंट() को कॉल करते समय मुझे एक त्रुटि मिलती है। दूसरी पंक्ति मुझे एक त्रुटि देता है, लेकिन मुझे समझ में नहीं आता क्यों, क्योंकि पहला काम करता है। केवल अंतर है f वर्ग Mat वर्ग का सदस्य नहीं है, लेकिन f2 है। विफलता है: error: no matching function for call to Mat::test(< unresolved overloaded function type>, int)'सी ++ - <अनसुलझा अधिभारित फ़ंक्शन प्रकार>

template <typename F> 
int Mat::test(F f, int v){ 
    return f(v); 
} 

int Mat::f2(int x){ 
    return x*x; 
} 

int f(int x){ 
    return x*x; 
} 

void Mat::print(){ 
    printf("%d\n",test(f ,5)); // works 
    printf("%d\n",test(f2 ,5)); // does not work 
} 

इस क्यों होता है?

+1

क्या 'f2' स्थिर है या नहीं? –

+0

printf को printf ("% d \ n", टेस्ट (Mat :: f2, 5) में बदलने का प्रयास करें; – 2to1mux

+0

क्या आपके पास 'f2' के एक से अधिक अधिभार हैं? –

उत्तर

3

समस्या यह है कि f2Mat पर एक विधि है, जबकि f केवल एक नि: शुल्क कार्य है। आप f2 को स्वयं से कॉल नहीं कर सकते हैं, इसे कॉल करने के लिए Mat के उदाहरण की आवश्यकता है। इस के आसपास सबसे आसान तरीका हो सकता है:

printf("%d\n", test([=](int v){return this->f2(v);}, 5)); 

= वहाँ this कब्जा है, जो कि तुम क्या f2 कॉल करने की आवश्यकता है।

+0

चूंकि f2 और प्रिंट मैट के दोनों सदस्य फ़ंक्शन हैं, इसलिए मैट ऑब्जेक्ट को संदर्भित किए बिना f2 को कॉल करने की अनुमति प्रिंट नहीं है? – 2to1mux

+0

वाह, यह काम करता है (मूल कोड से कुछ tweaks के साथ)। मेरे द्वारा +1 –

+0

-1। त्रुटि संदेश कहता है कि त्रुटि ओवरलोडेड फ़ंक्शन की वजह से होती है, और इसलिए नहीं क्योंकि फ़ंक्शन टेम्पलेट का फ़ंक्शन कॉल सिंटैक्स गलत है (जो आप कहते हैं)। –

31

pointer-to-member-function का प्रकार pointer-to-function से अलग है।

एक समारोह के प्रकार है कि क्या यह एक साधारण समारोह या कुछ वर्ग के एक गैर स्थिर सदस्य समारोह है पर निर्भर करता है अलग है:

int f(int x); 
the type is "int (*)(int)" // since it is an ordinary function 

और

int Mat::f2(int x); 
the type is "int (Mat::*)(int)" // since it is a non-static member function of class Mat 

नोट: अगर यह वर्ग फ्रेड का एक स्थिर सदस्य कार्य है, इसका प्रकार वही है जैसे कि यह एक सामान्य कार्य था: "int (*)(char,float)"

In C++, member functions have an implicit parameter which points to the object (the this pointer inside the member function). Normal C functions can be thought of as having a different calling convention from member functions, so the types of their pointers (pointer-to-member-function vs pointer-to-function) are different and incompatible. C++ introduces a new type of pointer, called a pointer-to-member, which can be invoked only by providing an object.

NOTE: do not attempt to "cast" a pointer-to-member-function into a pointer-to-function; the result is undefined and probably disastrous. E.g., a pointer-to-member-function is not required to contain the machine address of the appropriate function. As was said in the last example, if you have a pointer to a regular C function, use either a top-level (non-member) function, or a static (class) member function.

इस Here और here पर अधिक।

+0

पर कॉल करने के लिए कोई मिलान करने वाला फ़ंक्शन नहीं है लेकिन यह यह नहीं बताता कि टेम्पलेट क्यों इसे हल नहीं कर सकता या क्या मैं कुछ न कुछ भूल रहा हूं? –

+0

@LuchianGrigore इस तरह मैं इसे समझ गया। कंपाइलर एक प्रकार की अपेक्षा करता है जो 'कॉल ऑपरेटर' प्रदान करता है या देखता है कि क्या यह एक ऐसा फ़ंक्शन ढूंढ सकता है जो मैट :: टेस्ट से पहुंचने योग्य 'int f (int)' से मेल खाता हो। और उपरोक्त विवरण के अनुसार 'पॉइंटर-टू-सदस्य-फ़ंक्शन बनाम पॉइंटर-टू-फ़ंक्शन भिन्न और असंगत हैं। तो यह एक समारोह के रूप में 'this-> f2' से मेल नहीं खाएगा। यह सिर्फ मेरी समझ है। मुझे आज से पहले इस बारे में भी पता नहीं था :) –

+0

लिंक मरने लगते हैं। – derM

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