2011-12-29 9 views
5

मैं gcc 4.6.1 का उपयोग करके विविध टेम्पलेट पैरामीटर के साथ खेल रहा था।टेम्पलेट में फ़ंक्शन प्रकार संकलित नहीं करता है

template<typename RetType, typename... ArgTypes> 
class Event; 

template<typename RetType, typename... ArgTypes> 
class Event<RetType(ArgTypes...)> 
{ 
public: 
    typedef function<RetType(ArgTypes...)> CallbackType; 

    void emit(ArgTypes...args) 
    { 
     for (CallbackType callback : callbacks) 
     { 
      callback(args...); 
     } 
    } 

private: 
    vector<CallbackType> callbacks; 
}; 

लेकिन मेरे आश्चर्य निम्नलिखित "सामान्य" संस्करण है कि केवल एक "तर्क प्रकार" पर संकलन नहीं करता है:: निम्नलिखित कोड अपेक्षित ढंग से संकलित

template<typename RetType, typename ArgType> 
class Event; 

template<typename RetType, typename ArgType> 
class Event<RetType(ArgType)> // <- error: wrong number of template arguments (1, should be 2) 
{}; 

जी ++ 4.6.1 त्रुटि देता है टिप्पणी में के रूप में।

कोई भी जानता है कि यह त्रुटि क्यों उत्पन्न करता है और इसे कैसे काम करता है? साथ ही, क्या मैं उपरोक्त कोड को सोचने में सही हूं "टेम्पलेट आंशिक विशेषज्ञता" का एक रूप है?

उत्तर

4
template<typename RetType, typename ArgType> 
class Event; 

उम्मीद 2 टेम्पलेट तर्क, RetType और ArgType, आप केवल यह एक RetType(ArgType) दे।

template<typename RetType, typename... ArgType> 
class Event; 

उम्मीद 1 या अधिक टेम्पलेट तर्क, RetType और वैकल्पिकArgType रों।

+0

ऐसा लगता है कि संकलक रीटटाइप (ArgType) को फ़ंक्शन प्रकार की घोषणा के बजाए एक तर्क के रूप में सोचता है जो मेरा मतलब था। आश्चर्य की बात क्यों है कि यह वैचारिक घोषणा के समान ही इसका इलाज नहीं कर सकता है। और नहीं, यह रिकर्सन नहीं है। यहां विविधता तर्कों का उपयोग करने का मेरा इरादा फ़ंक्शन प्रकार की घोषणा को आगे बढ़ाने और फ़ंक्शन ऑब्जेक्ट्स का उपयोग करना है। –

+0

कोस: यह नहीं है। उस टिप्पणी को हटा दिया। – ronag

+0

एच Xu: मुझे नहीं लगता कि वैरिएड संस्करण काम करता है जैसा आप उम्मीद करते हैं। मुझे लगता है कि ArgTypes ... हमेशा जिस तरह से आप इसका उपयोग कर रहे हैं खाली हो जाएगा। – ronag

1

मुझे लगता है कि त्रुटि इस तथ्य के कारण है कि यदि टेम्पलेट भिन्न नहीं है, तो cpomiler मानक रूप की अपेक्षा करता है, जो वर्ग Event<templateArg1, templateArg2> है, जो स्पष्ट रूप से यह नहीं है कि आप इसे किस प्रकार खिला रहे हैं।

टेम्पलेट विशेषज्ञता के बारे में: मैं असहमत हूं, अगर मैं गलत नहीं कर रहा हूं तो आप कक्षा Event की घोषणा को आगे बढ़ाने के लिए हैं, तो प्रभावी रूप से इसे केवल 2 लाइनों के बाद घोषित करें।

+0

क्या इसका मतलब यह है कि यदि हम टेम्पलेट को टेम्पलेट तर्क के रूप में फ़ंक्शन प्रकार स्वीकार करना चाहते हैं तो हम केवल भिन्न तर्कों का उपयोग कर सकते हैं? मैं चाहता हूं कि फ़ंक्शन प्रकार को केवल एक तर्क के साथ सीमित करना है।मैंने कोड को संशोधित किया है, इसलिए अब वे सभी परिभाषाएं हैं। –

+0

क्षमा करें लोगों को अपने उद्देश्य से भ्रमित करने से बचने के लिए अब उन्हें आगे की घोषणाओं में बदलाव करना होगा, क्योंकि मैंने विशेष संस्करण के लिए एक सरल परिभाषा को जोड़ा है। सामान्य संस्करण को तत्काल नहीं किया जा सकता क्योंकि यह कार्यान्वयन नहीं करता है। यह उद्देश्य से है। –

+0

"क्या इसका मतलब यह है कि अगर हम टेम्पलेट को टेम्पलेट तर्क के रूप में फ़ंक्शन प्रकार स्वीकार करना चाहते हैं तो हम केवल भिन्न तर्कों का उपयोग कर सकते हैं?" हां और ना। विविध तर्कों के बिना आपको विभिन्न तर्कों के लिए विभिन्न टेम्पलेट्स बनाना होगा। यह बहुत आम है। उदाहरण के रूप में देखें https://github.com/pisto/hopmodv4/blob/master/src/hopmod/lua/push_function.hpp –

5

आप मनोरंजन के लिए std::function के अपने स्वयं के संस्करण बनाना चाहते हैं, यह इस तरह दिखना चाहिए:

template<class Signature> 
class Event; 

template<class R, class... Args> 
class Event<R(Args...)>{ 
    // ... 
}; 

क्यों अपने पहले संस्करण से काम करता है पहले से ही टेम्पलेट पैरामीटर में @ronag, एक पैरामीटर पैक (... द्वारा समझाया गया है) का अर्थ है शून्य या अधिक। यदि आप std::/boost::function के समान वर्ग (int(int, double, char) एक फ़ंक्शन प्रकार चाहते हैं, तो ऊपर दिए गए कोड अभी भी सही हस्ताक्षर हैं, इसलिए यह class Signature जैसे एकल प्रकार की घोषणा में फिट हो सकता है)।

+0

"... एक फ़ंक्शन प्रकार है, यही कारण है कि यह कक्षा हस्ताक्षर जैसे एकल प्रकार की घोषणा में फिट हो सकता है)।" - तो ऐसा लगता है कि जवाब है, एक फ़ंक्शन प्रकार, जैसे int (int, double), को संकलक द्वारा एकल प्रकार की घोषणा के रूप में माना जाता है? –

+0

@ एच जू: सही, यह एक ही प्रकार का है। – Xeo

+0

धन्यवाद ज़ीओ, आपका उत्तर मुझे रूट कारण से प्रेरित करता है। @ रोनाग का जवाब अन्य दर्शकों के लिए अधिक कठोर लगता है इसलिए मैंने उसे हरा टिक दिया। –

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