2010-04-29 13 views
6

मान लीजिए कि मेरे पास CallbackType नामक मनमाने ढंग से हस्ताक्षर के साथ एक बढ़ावा :: कार्य है।क्या प्रभावशाली ढंग से कार्य करने के लिए बूस्ट :: बाइंड का उपयोग करना संभव है?

  • यह boost::bind उपयोग करने के लिए एक समारोह है कि लगातार CallbackType रूप में एक ही तर्क लेता है लेकिन दो functors कॉल रचना के लिए संभव है?

मैं किसी भी संभावित समाधान के लिए खुला रहा हूँ, लेकिन यहाँ एक है ...

... काल्पनिक कुछ magic टेम्पलेट का उपयोग कर उदाहरण:

Template<typename CallbackType> 
class MyClass 
{ 
    public: 
     CallbackType doBoth; 

     MyClass(CallbackType callback) 
     { 
      doBoth = bind(magic<CallbackType>, 
          protect(bind(&MyClass::alert, this)), 
           protect(callback)     ); 
     } 

     void alert() 
     { 
      cout << "It has been called\n"; 
     } 
}; 

void doIt(int a, int b, int c) 
{ 
    cout << "Doing it!" << a << b << c << "\n"; 
} 

int main() 
{ 
    typedef boost::function<void (int, int, int)> CallbackType; 

    MyClass<CallbackType> object(boost::bind(doIt)); 

    object.doBoth(); 

    return 0; 
} 
+0

क्या 'जादू' को 'बांध' के संदर्भ में लागू किया जाना चाहिए? 'बाइंड' की भूमिका क्या है? निश्चित रूप से आप वास्तव में कॉलबैक में कुछ भी बाध्यकारी नहीं हैं। – Potatoswatter

+0

'जादू' शायद कुछ टेम्पलेट होगा जो स्वचालित रूप से एक मज़ेदार बनता है जिसने दो मज़ेदारों को तर्क के रूप में लिया है + 'कॉलबैक टाइप' के सभी तर्क ... लेकिन यह केवल मेरे लक्ष्य को स्पष्ट करने के लिए है, जरूरी नहीं कि एक यथार्थवादी समाधान प्रदान करें। मैं काफी अलग सुझावों के लिए खुला हूं। – Catskul

+0

क्या आप 'शून्य (int, int, int) 'के साथ' शून्य (शून्य)' लिखने की कोशिश कर रहे हैं? या वह सिर्फ एक टाइपो था? – MSN

उत्तर

8

बूस्ट पहले से ही बाध्य कार्यों का अनुक्रम बनाने का एक तरीका प्रदान करता है। Lambda's comma operator का प्रयोग करें।

using namespace boost::lambda; 
MyClass mc; 
CallbackType object = (bind(&MyClass::alert, mc), bind(doIt, _1, _2, _3)); 
object(1, 2, 3); 

इससे एक नया मज़ेदार, object तैयार होगा। जब आप उस तर्क को तीन तर्कों के साथ बुलाते हैं, तो यह doIt पर उन तर्कों को पार करने से पहले mc.alert() पर कॉल करेगा। कोष्ठक महत्वपूर्ण हैं।

काम करने के लिए ऊपर दिए गए मेरे उदाहरण के लिए, आपको alertconst फ़ंक्शन होने की आवश्यकता होगी। यदि इसे गैर-कॉन्स होने की आवश्यकता है, तो या तो सूचक से mc पर जाएं, या इसे boost::ref(mc) से लपेटें। और आपको Boost.Bambda के बजाय Boost.Lambda के bind का उपयोग करने की आवश्यकता होगी; उत्तरार्द्ध लैम्ब्डा के फ़ंक्शन-संयोजन ऑपरेटरों (विशेष रूप से अल्पविराम) के साथ संगत नहीं है।

+0

यह सी ++ 11 के 'std :: bind' के साथ कैसे काम करेगा? – Valerij

1
template< class Callback > 
struct pre_caller { 
    Callback c; 

    pre_caller(Callback in_c) : c(in_c) {} 

    void alert() {} // or an instance of a functor 

    operator() 
    { alert(); c(); } 

    template< class T1 > 
    operator(T1 a) // not sure if/what qualification to add to a 
    { alert(); c(a); } // or whether to attempt to obtain from 
         // function_traits<Callback>? 
    template< class T1, class T2 > 
    operator(T1 a, T2 b) 
    { alert(); c(a, b); } 

    template< class T1, class T2, class T3 > 
    operator(T1 a, T2 b, T3 c) 
    { alert(); c(a, b, c); } 

    // ad nauseam... and I mean nausea, maybe read up on Boost Preprocessor. 
}; 

बूस्ट बाइंड एक का उपयोग करता है इसके विविध वैडू के लिए बहुत से प्रीप्रोसेसर हैकिंग, और दुर्भाग्य से मुझे नहीं लगता कि यह हेड-पैचिंग के लिए एक पैटर्न या टूल्स प्रदान करता है जो अनिवार्य रूप से यह है।

+0

ऐसा लगता है कि एक आसान तरीका होना चाहिए, और शायद मेरा मेरा स्ट्रॉ मैन उदाहरण पूरी गलत दिशा में चला जाता है। एक बक्षीस शुरू करना, लेकिन यह जवाब के रूप में चिह्नित हो सकता है। – Catskul

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

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