2012-05-15 23 views
5

मैं सिर्फ पाया अपने आप को एक वर्गक्या मैं इस छोटी विधि कॉल कॉलिंग कक्षा के साथ पहिया को फिर से शुरू कर रहा हूं?

template <typename T> struct invoker { 
    void operator()(T& it) const {it();} 
}; 

बनाने तो मैं कुछ करने के लिए एक invoker<foo> (जो मेरे नियंत्रण में नहीं है) अलग foo उदाहरणों के साथ बार-बार उस पर invoker<foo>::operator()(foo&) कॉल करने के लिए, यह करने के लिए प्राप्त करना चाहता है जो गुजर सकता है उन कॉल को foo की foo::operator()() विधि पर अग्रेषित करें।

मुझे पता है कि यह केवल कुछ पंक्तियां हैं, लेकिन ऐसा लगता है कि यह संभवतः पहले से ही एसटीएल के कार्यात्मक, या boost::bind द्वारा प्रदान किया गया है। सिवाय इसके कि मैं एक चाल नहीं देख सकता, अगर कोई है। (मुझे यकीन है कि मैं पहले व्यक्ति बहुत कुछ इस तरह उपयोग करने के लिए नहीं कर रहा हूँ हूँ, करता है यह एक नाम है?)

+1

मुझे लगता है कि सी ++ 11 में इसके लिए कुछ भी है – pyCthon

+1

अभी के लिए मैं g ++ 4.4.5 पर हूं; मुझे नहीं लगता कि जी ++ को 4.5 तक लैम्बडा मिला है। यद्यपि एक पोस्ट किया गया है, तो एक लैम्ब्डा समाधान देखने के लिए उत्सुक; मैं अपने आवेदक वर्ग के साथ जी ++ संस्करण अपग्रेड तक रह सकता हूं। – timday

+0

आप 'foo :: ऑपरेटर()' को सीधे क्यों नहीं कॉल करेंगे? मेरा मतलब है, जिस वर्ग को 'इनवॉकर :: ऑपरेटर()' कहते हैं, उसे 'some_invoker (some_foo) जैसे कुछ करना है;', जबकि आप इसे इस तरह से कॉल कर सकते हैं: 'some_foo(); '। आप संकेत की एक अनावश्यक परत जोड़ रहे हैं। – mfontanini

उत्तर

5

हाँ, आप पहिया को फिर से शुरू कर रहे हैं। std :: mem_fun_ref जो आप चाहते हैं वह करता है।

std::vector<foo> foos; 

... 

std::for_each(foos.begin(), foos.end(), std::mem_fun_ref(&foo::operator())); 
वैकल्पिक रूप से

:

std::vector<foo*> foos; 

... 

std::for_each(foos.begin(), foos.end(), std::mem_fun(&foo::operator())); 

कि क्या आपके परम ptr या नहीं है एक को बढ़ावा देने :: mem_fn के महान लाभ है के साथ गड़बड़ करने के लिए नहीं।

कुछ भी इससे अधिक जटिल है और आप सी ++ 03 बाइंडर्स के साथ परेशानी में भागना शुरू करते हैं और boost.bind की तरह कुछ और अभिव्यक्ति की आवश्यकता है।

+4

सी ++ 11 में 'std :: mem_fun' और' std :: mem_fun_ref' को 'std :: mem_fn' के लिए बहिष्कृत किया गया है, बस इंगित करना चाहता था। –

6

ठीक है, आप std::bind उपयोग कर सकते हैं, शायद boost::bind रूप में अच्छी तरह समान व्यवहार प्राप्त करने के लिए:

#include <string> 
#include <iostream> 
#include <functional> 

struct foo { 
    void operator()() { 
     std::cout << "Hallo, im at addr: " << std::hex << this << std::endl; 
    } 
}; 

int main() { 
    std::function<void(foo*)> fun = std::bind(&foo::operator(), std::placeholders::_1); 
    foo f1, f2; 
    fun(&f1); 
    fun(&f2); 
} 

आउटपुट:

Hallo, im at addr: 0xbffc396a 
Hallo, im at addr: 0xbffc3969 

आप तर्क प्रकार के लिए एक टेम्पलेट वर्ग का उपयोग करते हैं, तो आप पहिया पुनर्रचना के बिना एक ही behvaiour हो सकता है।

संपादित: के रूप में पागल एडी ने कहा, तुम सिर्फ boost::mem_fn या std::mem_fn उपयोग कर सकते हैं:

std::function<void(foo*)> fun = std::mem_fn(&foo::operator()); 

के बजाय bind

+1

आपको वास्तव में यहां बांधने की आवश्यकता नहीं है और इसे छोड़ना उचित हो सकता है। बाइंड को दो तर्क सूचियों को मर्ज करने और लक्ष्य कॉल करने योग्य को आमंत्रित करने के लिए एक तर्क रूपांतरण प्रणाली से गुज़रना पड़ता है। boost :: mem_fn चाल करेगा और वास्तव में बाइंड() सदस्य पॉइंटर्स के लिए इसका उपयोग करता है। –

+0

@CrazyEddie अच्छा है, मैंने कुछ समय पहले 'mem_fn' का उपयोग किया है, लेकिन इसके बारे में पूरी तरह से भूल गया है। मेरा जवाब संपादित किया गया: डी – mfontanini

+0

ठीक है यह वही चीज है जिसे मैं धन्यवाद के लिए देख रहा था; जब आप इसे देखते हैं तो यह स्पष्ट होता है, थोड़ा सा मैं किसी भी तरह से खुद को आश्वस्त करता हूं (यहां बहुत देर हो चुकी है) क्योंकि जिस फू विधि में मुझे रूचि थी, उसके पास कोई तर्क नहीं था, _1 प्लेसहोल्डर के लिए कोई भूमिका नहीं थी ... तो गलत। – timday