के आसान बनाने में करते हैं बस के बीच अंतर पर विचार करने के लिए:
template <class C, class M> void f(C (M::*member)());
template <class C, class M> void g(C (M::*member));
f
में, member
शून्य तर्क लेने और C
लौटने लौटने M
के एक सदस्य के कार्य करने के लिए एक सूचक है। यदि आपने इसे &B::func
के साथ बुलाया है, तो संकलक M == B
और C == void
को घटाएगा। सीधा।
g
में, member
प्रकार C
की M
के एक सदस्य के लिए सिर्फ एक सूचक है। लेकिन, हमारे मामले में, &B::func
एक समारोह है। तो यहां प्रभाव सिर्फ सूचक को छोड़ रहा है। हम M == B
फिर से घटाते हैं, जबकि C
void()
बन जाता है - अब C
फ़ंक्शन प्रकार है। यह के संस्करण के संस्करण में है, जिसमें यह अधिक प्रकार के सदस्यों की अनुमति देता है। g
सीवी - योग्य सदस्य functinos के खिलाफ तर्क लेने वाले कार्यों के खिलाफ, या सदस्यों के लिए पॉइंटर्स के खिलाफ, या प्रासंगिक रूप से उन कार्यों के खिलाफ मिलान कर सकता है।
के एक ओवरलोड समारोह एक उदाहरण के रूप पर विचार करें और कैसे यह अलग ढंग से निष्कर्ष निकाला जायेगा (इससे आपके प्रश्न का है, जो बाद से संपादित किया गया है में मूल समस्या दिलचस्प था, लेकिन अभी भी):
struct X {
void bar() { }
void bar(int) { }
};
जब हम कार्य करें:
f(&X::bar);
भी &X::bar
हालांकि एक ओवरलोड नाम है, केवल एक ही वास्तव में C (M::*)()
मेल खाता है। जिस पर M == X
और C == void
है। का ओवरलोड लोड करने का कोई तरीका नहीं है कि int
टेम्पलेट प्रकार से मेल खाता है। तो यह अधिभारित नाम पारित करने के स्वीकार्य उपयोगों में से एक है। यह ठीक है।
हालांकि, जब हम करते हैं:
g(&X::bar);
अब, वहाँ दो पूरी तरह से vaild कटौती कर रहे हैं। C
void()
और void(int)
दोनों हो सकता है। चूंकि दोनों मान्य हैं, कटौती संदिग्ध है, और आप संकलित करने में विफल रहते हैं - एक त्रुटि के साथ जो वास्तव में यह विशेष रूप से स्पष्ट नहीं करता है।
अब वापस अपने उदाहरण के लिए:
call1(&B::func2, this); // Error: no matching member function for call to 'call2'
call2(&B::func2, this); // works
&B::func2
के प्रकार void (B::*)() const volatile
है। चूंकि call1
सदस्य फ़ंक्शन प्रकार पर कटौती करता है जो कोई तर्क नहीं लेता है और सीवी-योग्य नहीं है, प्रकार की कटौती बस विफल हो जाती है।उन प्रकारों को मिलान करने के लिए C
या M
नहीं है।
हालांकि, call2
कटौती ठीक है क्योंकि यह अधिक सामान्य है। यह सदस्य के लिए किसी भी सूचक से मेल खा सकता है। हम बस C = void() const volatile
के साथ समाप्त होते हैं। यही कारण है कि यह काम करता है।
मुझे यह भी पता नहीं था कि 'सी (एम :: * सदस्य) 'मान्य वाक्यविन्यास है ... –
बिंदु यह है कि' कॉल 1 'सीवी-क्वालीफायर के साथ कार्यों को स्वीकार नहीं करेगा, जबकि' कॉल 2 'अनुमति देता है। – Crossfire
असंबद्ध लेकिन सदस्य कार्य को सीधे कॉल करने के बजाय 'std :: bind' का उपयोग क्यों परेशान करते हैं? '(उदाहरण -> * सदस्य)();' –