2016-12-06 12 views
6
#include <iostream> 
#include <deque> 

using namespace std; 
main() 
{ 
    typedef void (deque<int>::*func_ptr)(int); 
    func_ptr fptr = &deque<int>::push_back; 
} 

इम इस समारोह के लिए सूचक प्राप्त करने की कोशिश लेकिन मैं एक संकलन त्रुटिसूचक :: push_back

error: cannot convert ‘void (std::deque<int>::*)(const value_type&) {aka void (std::deque<int>::*)(const int&)}’ to ‘func_ptr {aka void (std::deque<int>::*)(int)}’ in initialization 
    func_ptr fptr = &deque<int>::push_back; 

मिल मैं इतना है कि मैं पर विभिन्न सदस्य कार्यों के लिए सूचक प्राप्त कर सकते हैं ऐसा करना चाहते हैं विभिन्न स्थितियों का आधार।

मैंने this link का उल्लेख किया। त्रुटि संदेश के रूप में कहा गया है

+0

आपके द्वारा लिंक किए गए व्याख्यान नोट्स अब सार्वजनिक रूप से सुलभ नहीं हैं। – ti7

+0

@ ti7 मैं अभी भी इसे एक्सेस करने में सक्षम हूं। – harman786

उत्तर

1

push_back(), एक const T & पैरामीटर लेता है:

परिवर्तित नहीं कर सकते 'शून्य (std :: Deque :: *) (स्थिरांक VALUE_TYPE &) ...

बदलें अपने प्रकार उर्फ ​​करने के लिए:

typedef void (deque<int>::*func_ptr)(const int &); 
+1

या 'ऑटो' लिखें ... –

+2

@LightnessRacesinOrbit - क्योंकि समारोह ओवरलोड हो गया है का उपयोग करते हुए 'auto', यहाँ एक संकलन त्रुटि हो जाएगा, और ऑटो पता नहीं होगा जो दिया समारोह नाम के साथ संबद्ध करने ओवरलोड। – cyberbisson

-1

तुम क्या करने कोशिश कर रहे हैं के साथ एक बड़ा समस्या है। कार्यान्वयन को किसी भी सदस्य फ़ंक्शंस में डिफ़ॉल्ट पैरामीटर जोड़ने की अनुमति है, इसलिए push_back() के लिए वास्तविक हस्ताक्षर भिन्न हो सकता है। यह एक ही नाम के साथ अतिरिक्त कार्यों को भी जोड़ सकता है (लेकिन एक अलग हस्ताक्षर)।

मैं पॉइंटर्स को कंटेनर सदस्यों के कार्य में लेने के खिलाफ सलाह देता हूं। आप इसके बिना आमतौर पर बेहतर होते हैं।

+0

डाउनवॉटर कारणों की व्याख्या करें? – SergeyA

+0

मैं नीचे वोट आपने नहीं किया है, लेकिन मुझे लगता है कारण था क्योंकि प्रतिक्रिया कैसे ओपी इस समारोह के लिए एक सूचक मिलना चाहिए के मूल प्रश्न का समाधान नहीं किया। शायद, एक उत्तर और ओपी के दृष्टिकोण के लिए आपका प्रतिलेख शायद अकेला छोड़ दिया गया होगा। दोबारा, मैंने ऐसा नहीं किया। :) – cyberbisson

3

के रूप में कहा स्वीकार किए जाते हैं जवाब में, समस्या यह है कि प्रकार हस्ताक्षर अलग है - एक std::deque<T> के लिए, push_back केवल एक अधिभार कि T const& स्वीकार करता है और सीधे नहीं T है। typedef void (deque<int>::*func_ptr)(const int &) इसे लिखने के लिए एक बिल्कुल संक्षिप्त और क्रांतिकारी तरीका है।

मैं ऐसा करने के लिए एक सी ++ 11 तरीके को संबोधित करना चाहता था - उपनाम टाइप करें। सबसे पहले आश्चर्य हो सकता है कि "auto का उपयोग क्यों नहीं करें?" यह संभव नहीं है क्योंकि फ़ंक्शन का उपयोग किया जा रहा है एक अधिभारित फ़ंक्शन है, और auto नहीं जानता कि किस ओवरलोड को एक्सेस करना है। चूंकि मूल प्रश्न फ़ंक्शन प्रकार के ज्ञान को void(int) पर एम्बेड करता है, इसलिए कथन &deque<int>::push_back सही अधिभार का चयन करता है। सरल कथन के साथ समस्या यह है कि यह कंटेनर और उस प्रकार के ज्ञान के ज्ञान में बेक है। यदि आप std::vector में बदलना चाहते हैं, या int से short पर बदलना चाहते हैं, तो आपको सभी नए प्रकार बनाना होगा। प्रकार उपनाम के साथ, हम embedding प्रकार ज्ञान से बचने के लिए सब कुछ templatize कर सकते हैं:

using func_ptr = void(Cont::*)(typename Cont::const_reference); 

हम कुछ सरल, के रूप में पहले कर सकते हैं:

func_ptr<deque<int>> fptr = &deque<int>::push_back; 

... या हम कहीं न कहीं एक कंटेनर का उल्लेख कर सकते हैं:

vector<short> container; 

... संकलन समय पर अपने प्रकार को देख, और इसकी push_back कार्य करने के लिए एक सूचक भंडारण, सभी की देखभाल क्या कंटेनर है बिना:

using container_type = decltype(container); 
func_ptr<container_type> fptr2 = &container_type::push_back; 
संबंधित मुद्दे