2013-07-05 12 views
6

निम्नलिखित कोड वैध दिखता है, लेकिन संकलन नहीं हैटेम्पलेट वर्ग

void f() {} 

template<bool> 
struct call_any 
{ 
    template<typename F> 
    static void call(F f) {} 
}; 

template<bool B> 
void call_f() 
{ 
    call_any<true>::call<void (&)()>(f); // OK 
    call_any<false>::call<void (&)()>(f); // OK 
    call_any<B>::call<void()>(f);   // OK 
    call_any<B>::call<void (&)()>(f); // expected primary-expression before '>' 
} 

क्यों एक त्रुटि है और इसका क्या मतलब है की टेम्पलेट विधि के लिए पैरामीटर के रूप में समारोह गुजर?

उत्तर

10

जब आप टेम्पलेट के भीतर टेम्पलेट पैरामीटर पर निर्भर प्रकारों से निपट रहे हैं, तो संकलक यह नहीं जानता कि उस प्रकार के सदस्य किस प्रकार की चीजें हैं। जब तक आप अन्यथा निर्दिष्ट नहीं करते हैं, यह मानता है कि सदस्य प्रकार नहीं हैं और टेम्पलेट नहीं हैं। इस वजह से, यह कम से कम ऑपरेटर के रूप में < का इलाज करने का प्रयास कर रहा है, लेकिन > तक पहुंचने तक अभिव्यक्ति को पार्स करना असंभव हो जाता है।

त्रुटि से छुटकारा पाने के लिए आप इस के बजाय का उपयोग करना चाहिए:

call_any<B>::template call<void (&)()>(f); 

इस संकलक स्पष्ट रूप से वह call एक टेम्पलेट है बताता है, तो यह टेम्पलेट मापदंडों और नहीं एक की शुरुआत के रूप < व्यवहार करना चाहिए ऑपरेटर से नियमित रूप से कम।

यह रूप में अच्छी तरह template उपयोग करना चाहिए:

(call_any<B>::call < void()) > (f); 
:

call_any<B>::call<void()>(f); 

एकमात्र कारण आप इस लाइन पर त्रुटि नहीं दिख रहा है एक गैर टेम्पलेट के रूप में पार्स करने के लिए एक तरह से है कि वहाँ है

हालांकि विषम, यह सिंथेटिक रूप से मान्य है, इसलिए संकलक उस रेखा से पहले हो जाता है, और आप जो पहली त्रुटि देखते हैं वह वह है जिसे आप उल्लेख करते हैं। हालांकि, template कीवर्ड के बिना, आपको अंततः एक त्रुटि मिल जाएगी जब call_f वास्तव में तत्काल हो गया था (शायद - अजीब तरीके से यह काम कर सकता है)।

पहले दो उदाहरण template कीवर्ड का उपयोग किये बिना ठीक हैं। चूंकि प्रकार टेम्पलेट पैरामीटर पर निर्भर नहीं है, इसलिए यह निर्धारित किया जा सकता है कि call एक टेम्पलेट है जबकि call_f पार्स किया जा रहा है।

आप पूछ सकते हैं: "कंपाइलर यह आंकड़ा क्यों नहीं ले सकता है? मैंने इसे ऊपर दिए गए कोड में टेम्पलेट के रूप में परिभाषित किया है!"। मुद्दा विशेषज्ञता है। आप टेम्पलेट के विशेषज्ञ और कुछ क्या प्राथमिक टेम्पलेट द्वारा निर्धारित से पूरी तरह से अलग कर सकता है:

template<> 
struct call_any<false> 
{ 
    static const int call = 5; 
}; 

इस विशेषज्ञता हो सकता है के बाद भी call_f परिभाषित किया गया है, इसलिए संकलक पर क्या call_any के लिए प्राथमिक टेम्पलेट का कहना है जब भरोसा नहीं कर सकते यह call_f पार्सिंग है।

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