2011-02-07 8 views
5

के लिए बहस मैं ऐसी है कि वह बाद में कहा जा सकता है इस समस्या को जहां एक सी ++ समारोह सूचक सहेजा जाता है तर्क का एक सेट के साथ एक साथ, उस पर कॉल करने के लिए है। कॉलिंग कोड कार्यों के प्रकार और तर्क से अनजान है। फ़ंक्शन पॉइंटर्स और तर्कों को सहेजना और कॉल करना मेरे आवेदन में बेहद महत्वपूर्ण है। इंटरफेस कुछ इस तरह दिखना चाहिए:की बचत समारोह सूचक + बाद में उपयोग के

void func(int a, char * b); 
call_this_later(func, 5, "abc"); 

एक सरल समाधान बुलाया समारोह प्रति एक अलग typedef की आवश्यकता होती है एक functor में इस जानकारी के सभी डाल करने के लिए, है। सी ++ 11 मुझे एक वैरिएडिक टेम्पलेट का उपयोग करने की अनुमति देगा, तो यह ठीक है।

के बाद से functor के प्रकार के कॉल के बिंदु पर ज्ञात नहीं है, यह इन functors के लिए एक आभासी आधार वर्ग बनाने के लिए और आभासी समारोह कॉल का उपयोग functors आह्वान करने के लिए आवश्यक है। वर्चुअल फ़ंक्शन कॉल का प्रदर्शन ओवरहेड + हीप आवंटन बहुत अधिक है (मैं इस मुहावरे को यथासंभव कुछ असेंबली निर्देशों के साथ लागू करने की सीमाओं को दबा रहा हूं)। तो मुझे एक अलग समाधान की जरूरत है।

कोई विचार?

उत्तर

0

आपको अपने आवंटन पैटर्न से मेल खाने के लिए कस्टम आवंटन की आवश्यकता होगी। वैकल्पिक रूप से, कॉल साइट पर फ़ैक्टर के प्रकार को पारित करने के लिए संकलन-समय बहुरूपता का उपयोग करें।

3

क्या एक समाधान boost::function/boost::bind उपयोग के बारे में:

void func(int a, char * b); 

boost::function<void()> my_proc = 
    boost::bind(&func, 5, "abc"); 

// then later... 

my_proc(); // calls func(5, "abc"); 
+1

मेरा मानना ​​है कि ':: boost :: function' और ':: std :: tr1 :: function' वही करता है जो @ हंस नहीं करना चाहता। मुझे लगता है कि वे आभासी कार्यों और गतिशील आवंटन का उपयोग करते हैं। – Omnifarious

+0

@ ओमनिफरीस: किसी भी गतिशील आवंटन के लिए उपयोग किए जाने वाले फ़ंक्शन/मज़ेदार पर निर्भर करता है। पीओडी प्रकारों की छोटी संख्या वाले कार्यों के लिए, आंतरिक भंडारण होता है जो इसका उपयोग करेगा, हालांकि, हां यह वास्तव में फ़ंक्शन कॉल करने के लिए एक प्रकार की (बहुत गहराई से) छुपी वर्चुअल तालिका का उपयोग करता है। – diverscuba23

2

आप एक लैम्ब्डा अभिव्यक्ति जो प्रकार कब्जा के साथ ऐसा कर सकता है।

template <typename Func, typename Arg1, typename Arg2> 
std::function<void(void)> call_this_later(Func f, Arg1 a1, Arg2 a2) { 
    return [=]() { f(a1, a2); }; // Capture arguments by value 
} 
कुछ बातें

गौर करने योग्य

  1. मैं, नहीं लगता है कि तुम यहाँ सही अग्रेषण का उपयोग कर सकते, क्योंकि आप तर्क
  2. के बाद से सी ++ कचरा एकत्र नहीं है पर कब्जा करने की क्या ज़रूरत है अगर तर्क पॉइंटर्स हैं वे बाद में जिंदा नहीं है कि कुछ ऐसा इंगित कर सकते हैं। उदाहरण के लिए यदि आपका तर्क const char* है तो यह ठीक है अगर आप स्ट्रिंग अक्षर के साथ इसका उपयोग करते हैं, लेकिन यदि आप someStdString.c_str() पास करते हैं और स्ट्रिंग जल्द ही किसी भी समय मरने जा रही है।
  3. मैंने दो तर्कों के साथ उदाहरण दिया, यदि आपका कंपाइलर वैरिएड टेम्पलेट्स का समर्थन करता है तो आप उन लोगों का उपयोग कर सकते हैं अन्यथा केवल तर्कों की संख्या के लिए एक ओवरलोड बनाएं।
संबंधित मुद्दे