2010-09-16 41 views
5

से पैरामीटर 1 को परिवर्तित नहीं कर सकता है अब मैं बूस्ट बाइंड & mem_fn का उपयोग करने का प्रयास कर रहा हूं। लेकिन ओवरलोडेड-फ़ंक्शन को बांधने में कोई समस्या है। अनुवर्ती कोड की संकलन त्रुटि को हल करने के लिए कैसे करें?'ओवरलोडेड-फ़ंक्शन' से '...'

boost::function< void(IF_MAP::iterator) > bmf = std::mem_fun1< void, IF_MAP, IF_MAP::iterator >(&IF_MAP::erase); 
boost::function< void(IF_MAP::iterator) > bmf = boost::mem_fn< void, IF_MAP, IF_MAP::iterator >(&IF_MAP::erase); 

मुख्य उद्देश्य का पालन कोड

IF_MAP M; 
boost::function< void(IF_MAP::iterator) > bmf = boost::bind(
    boost::mem_fn< void, IF_MAP, IF_MAP::iterator >(&IF_MAP::erase), 
    &M, _1); 
M.insert(IF_MAP::value_type(1, 1.f)); M.insert(IF_MAP::value_type(2, 2.f)); 
bmf(2); 

संकलन त्रुटि संदेश इस तरह कर रहे हैं संकलित करने के लिए है ...

त्रुटि C2665: 'को बढ़ावा देने :: mem_fn': से कोई भी 2 अधिभार सभी तर्क प्रकारों को परिवर्तित कर सकते हैं 'boost :: _ mfi :: mf1 boost :: mem_fn :: iterator> (आर (__thiscall std :: map < _Kty, _Ty> :: *) (ए 1))' या 'boost :: _ mfi :: cmf1 boost :: m em_fn :: iterator> (आर (__thiscall std :: नक्शा < _Kty, _Ty> :: *) (A1) स्थिरांक) '

पी.एस. यू जानते हैं, std :: मानचित्र 3 अतिभारित है मिटा सदस्य समारोह

  1. void erase(iterator _Where)
  2. size_type erase(const key_type& _Keyval)
  3. void erase(iterator _First, iterator _Last) 2 समारोह आसानी से आबद्ध किया जा सकता है, लेकिन दूसरों को नहीं।

संपादित
और अधिक विस्तार में मेरे सवाल का वर्णन करने के लिए:

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

अब मैं कुछ विरासत कोडों का पुन: उपयोग कर रहा हूं। आजकल, मैं आमतौर पर कोड के इस पैटर्न की तरह दिखता हूं। (वास्तविक कोड अधिक जटिल हैं लेकिन लगभग निम्नानुसार हैं) डुप्लिकेट erase() कॉल इस फ़ंक्शन में बिखरे हुए हैं।

typedef map< int, float > IF_MAP; 

bool DoAndPopOld(IF_MAP& M, int K) 
{ 
    IF_MAP::iterator Itr = M.find(K); 
    if (Itr == M.end()) return false; 

    if (K < 10) 
    { 
     M.erase(Itr); // erase call is here... 
     return false; 
    } 

    if (100 < K) 
    { 
     // Do something 
     M.erase(Itr); // and here... 
     return true; 
    } 

    // Do something 
    M.erase(Itr); // and also here! 

    return true; 
} 

तो, मैं इस तरह कोड ऊपर पुनर्रचना करना चाहते हैं ...

class ScopedOutCaller 
{ 
private: 
    boost::function< void() > F; 
public: 
    ScopedOutCaller(boost::function< void() > _F) : F(_F) {} 
    ~ScopedOutCaller() { F(); } // deferred function call 
}; 

bool DoAndPopNew(IF_MAP& M, int K) 
{ 
    IF_MAP::iterator Itr = M.find(K); 
    if (Itr == M.end()) return false; 

    // Make deferred call, so I do not consider calling erase function anymore. 
    ScopedOutCaller SOC(boost::bind(&IF_MAP::erase), &M, Itr); 

    if (K < 10) 
    { 
     // M.erase(Itr); <-- unnecessary 
     return false; 
    } 
    if (100 < K) 
    { 
     // Do something 
     // M.erase(Itr); <-- unnecessary 
     return true; 
    } 

    // Do something 
    // M.erase(Itr); <-- unnecessary 
    return true; 
} 

लेकिन, जैसा कि मैंने पूछा ... संकलन त्रुटियां हुईं कर रहे हैं। मैं जो करना चाहता हूं उससे लंबा और छोटा यह है कि फ़ंक्शन कॉल को कैसे रोकें। कृपया मुझे स्थगित कॉल करने का तरीका बताएं। धन्यवाद।

+1

मैं सवाल है, जहां यह है में अपने "जवाब" से जानकारी ले जाया गया माना जाता है। यदि आपके पास अतिरिक्त जानकारी है, तो कृपया इसे प्रश्न में संपादित करें। यदि आप इसे उत्तर के रूप में पोस्ट करते हैं, तो यह केवल भ्रमित होता है (और अधिक महत्वपूर्ण बात यह है कि लोग उत्तर देने से पहले नहीं देखेंगे) – jalf

+0

ठीक है, क्या आप केवल वीसी की परवाह करते हैं या नहीं? –

+0

@ जॉर्ज मैं आमतौर पर एमएसवीएस का उपयोग करता हूं, लेकिन अगर आपको कोई विचार है, तो कृपया मुझे कुछ बताएं। धन्यवाद। – codevania

उत्तर

3

std::map एस सदस्य फ़ंक्शन erase() ओवरलोड हो गया है, इस प्रकार आपको मैन्युअल रूप से असंबद्ध होना है - Boost.Bind FAQ देखें।

उदा। size_type erase(const key_type&) अधिभार के लिए:

typedef IF_MAP::size_type (IF_MAP::*EraseType2)(const IF_MAP::key_type&); 
boost::function<void (const IF_MAP::key_type&)> bmf2; 
bmf2 = boost::bind((EraseType2)&IF_MAP::erase, &M, _1); 

चयन करने के लिए अन्य संस्करणों बस प्रकार आप कास्ट कर रहे हैं, उदाहरण के लिए बदल:

// 1. void erase(iterator position) : 
typedef void (IF_MAP::*EraseType1)(IF_MAP::iterator); 
boost::function<void (IF_MAP::iterator)> bmf1; 
bmf1 = boost::bind((EraseType1)&IF_MAP::erase, &M, _1); 

// 3. void erase(iterator first, iterator last) : 
typedef void (IF_MAP::*EraseType3)(IF_MAP::iterator, IF_MAP::iterator); 
boost::function<void (IF_MAP::iterator, IF_MAP::iterator)> bmf3; 
bmf3 = boost::bind((EraseType3)&IF_MAP::erase, &M, _1, _2); 

दुर्भाग्य से दृश्य स्टूडियो सी ++ 03 यहाँ (एक बार फिर से ...) के लिए गैर-अनुरूप है और आपको निम्न दो रूपों का उपयोग करना पड़:

typedef IF_MAP::iterator (IF_MAP::*EraseType1)(IF_MAP::const_iterator); 
typedef IF_MAP::iterator (IF_MAP::*EraseType3)(IF_MAP::const_iterator, 
               IF_MAP::const_iterator); 

VC8 और आप VC9 के साथ _HAS_STRICT_CONFORMANCE का उपयोग कर उस समस्या को हल कर सकते हैं, लेकिन यह वीसी 10 के साथ फिर से टूट जाता है क्योंकि सी ++ 0x erase() ओवरलोड को डिनक्यूमवेयर द्वारा उपयोग किए गए फॉर्मों में बदलता है (N3092, 23.4.1 देखें)।
पोर्टेबिलिटी के लिए मैं इन परेशान समस्याओं के आसपास पाने के लिए एक रैपर फ़ंक्शन का उपयोग करने के लिए जाऊंगा; यदि आप केवल वीसी के बारे में परवाह करते हैं तो मैंने ऊपर दिए गए प्रकारों का उपयोग करें।

ब्लॉक निकास पर परिणामी फ़ैक्टर को निष्पादित करने के लिए, सबसे आसान तरीका Boosts shared_ptr या एक समान स्कोप गार्ड का उपयोग करना है। जैसे कुलपति विशिष्ट कलाकारों के लिए:

typedef IF_MAP::iterator (IF_MAP::*EraseType)(IF_MAP::const_iterator); 
boost::shared_ptr<void> guard(static_cast<void*>(0), 
           boost::bind((EraseType)&IF_MAP::erase, &M, Itr)); 
+0

आपके उत्तर के लिए Thans। हाँ .. जैसा कि आपने बताया है, सदस्य कार्य को मिटाया जा सकता है (मैंने किया)। लेकिन मैं अन्य अधिभारित फ़ंक्शन को बांधना चाहता हूं ... जैसे, शून्य मिटाना (इटरेटर _ कहीं भी) या शून्य मिटाना (इटरेटर _ फर्स्ट, इटरेटर _लास्ट)। ^^; क्या आपको कोई विचार है? – codevania

+0

@codevania: निश्चित रूप से, यह पूरी तरह से एक ही प्रक्रिया है - बस उस प्रकार को बदलें जिसे आप कास्टिंग कर रहे हैं। –

+0

बहुत बहुत धन्यवाद जॉर्ज। लेकिन ऊपर दिए गए कोड यू के ऊपर 'टाइप-कास्ट त्रुटि' के कारण संकलित नहीं किया गया है। – codevania

0

इस प्रयास करें:

ScopedOutCaller SOC(boost::bind(static_cast< IF_MAP::iterator (IF_MAP::*)(IF_MAP::const_iterator) >(&IF_MAP::erase), &M, Itr)); 

और विजुअल स्टूडियो 2005 के लिए:

ScopedOutCaller SOC(boost::bind(static_cast< IF_MAP::iterator (IF_MAP::*)(IF_MAP::iterator) >(&IF_MAP::erase), &M, Itr)); 
+0

मैं देखता हूं ... सही हस्ताक्षर "IF_MAP :: इटरेटर (IF_MAP :: *) (IF_MAP :: iterator)" नहीं "शून्य (IF_MAP :: *) (IF_MAP :: iterator)" – codevania

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