2011-10-26 20 views
7

मैं बहुत की तरह एक विधि के माध्यम से एक std :: समारोह पारित करने के लिए प्रयास कर रहा हूँ के रूप में समारोह:C++ 0x std :: एक विधि तर्क

class dispatch 
{ 
    public: 
    deliver(std::function<void (void)> task); 
} 

यह अपेक्षा के अनुरूप काम करता है। हालांकि मैं कार्य के रूप में आपूर्ति की गई कुछ विधियों के लिए तर्क पारित करना चाहता हूं लेकिन सभी अलग-अलग फ़ंक्शन < ...> रूपों के लिए अधिभार बनाना नहीं चाहता।

उदाहरण के लिए

तरह

deliver(std::function& task); 

इस प्रकार यह बिल्कुल संभव सिर्फ एक विधि बनाने के लिए और बस के साथ

dispatch->deliver(bind(&Object::method, X)); 

या

dispatch->deliver(bind(&Object::method, X, arg1, arg2)); 

आदि आह्वान ...

है

धन्यवाद हर इनपुट के लिए। यह दिखाई देगा कि मेरी वास्तविक गलती प्रेषण के लिए कॉल के साथ है-> अतिरिक्त तर्क के साथ वितरित करना भी एक बाध्य कॉल है।

dispatch->deliver(bind(&Object::method1, X1, bind(&Object::method1, X2)); 

error: /usr/include/c++/v1/functional:1539:13: error: no matching function for call to '__mu_expand' return __mu_expand(__ti, __uj, __indices());

+0

कक्षा घोषणा के बाद '' 'गुम है। :-) –

उत्तर

9

std::function<void(void)> है कि यह की पूरी बात है पहले से ही बहुरूपी है। तो उन दो अंतिम स्निपेट काम करेंगे (जब तक कि मज़ेदार bind रिटर्न को कोई तर्क नहीं दिया जा सकता है, और निश्चित रूप से कुछ भी नहीं लौटाता है), जो आपके पास पहले से बदल रहा है।

3

हाँ, यह जब तक आप बाँध का उपयोग संगत समारोह वस्तुओं उत्पन्न करने के लिए संभव है:

#include <boost/bind.hpp> 
#include <boost/function.hpp> 
#include <iostream> 
#include <list> 
#include <string> 

typedef boost::function<void(void)> fun_t; 
typedef std::list<fun_t> funs_t; 

void foo() 
    { std::cout <<"\n"; } 
void bar(int p) 
    { std::cout<<"("<<p<<")\n"; } 
void goo(std::string const& p) 
    { std::cout<<"("<<p<<")\n"; } 

void caller(fun_t f) 
    { f(); } 

int main() 
{ 
    funs_t f; 
    f.push_front(boost::bind(foo)); 
    f.push_front(boost::bind(bar, int(17))); 
    f.push_front(boost::bind(goo, "I am goo")); 

    for (funs_t::iterator it = f.begin(); it != f.end(); ++it) 
    { 
     caller(*it); 
    } 

    return 0; 
} 

(ध्यान दें, मैं Boost.Function और Boost.Bind उपयोग करते हैं, लेकिन वहाँ के उपयोग करने के लिए कोई फर्क नहीं होना चाहिए std :: bind और std :: function।)

+0

क्या मुझे मूल्य या संदर्भ से 'fun_t' पास करना पसंद है? – hkBattousai

+0

@hkBattousai यह निर्भर करता है। Http://stackoverflow.com/a/8711486/151641 और http://stackoverflow.com/a/18366273/151641 – mloskot

1
class dispatch 
{ 
    public: 
    template <typename ... Params> 
    deliver(std::function<void (Params && p...)> task, Params && p) 
    { 
     task(std::forward(p)...); 
    } 
}; 

मैंने इसे संकलित नहीं किया है (सुधार स्वागत है!), लेकिन विचार काम करना चाहिए।

dispatch->deliver(bind(&Object::method, X)); 
dispatch->deliver(bind(&Object::method, X, arg1, arg2)); // OR! 
dispatch->deliver(bind(&Object::method, X), arg1, arg2); 

एक बात मैं के बारे में स्पष्ट नहीं कर रहा हूँ कि यह कैसे बर्ताव करता है, तो Object::method भार के के बजाय पैरामीटर चूक गया है।

+0

+1: एक नाइटपिक, std :: फ़ंक्शन को कॉन्स्ट संदर्भ के रूप में पास करने के लिए यह अधिक कुशल हो सकता है । – mirk

+0

@DirkM आप सही हैं, लेकिन चूंकि ओपी ने ऐसा नहीं किया, इसलिए मैंने भी नहीं चुना। वह उस डिलिवरी विधि में कुछ कर रहा था जो "डिलीवरी" से जुड़ा नहीं है। मुझे आशा है कि हालांकि नहीं। –

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