2010-10-29 13 views
20

नीचे कोड संकलन पास नहीं कर सका, इस कंपाइलर त्रुटि के लिए क्या विचार है?एक स्पष्ट टेम्पलेट विशेषज्ञता के लिए डिफ़ॉल्ट तर्क निर्दिष्ट क्यों नहीं किया जा सकता है?

template<class T> void f(T t) {}; 

template<> void f<char>(char c = 'a') {} 

त्रुटि संदेश: डिफ़ॉल्ट तर्क एक समारोह टेम्पलेट

+0

मामूली टिप्पणी: फ़ंक्शन परिभाषा के बाद आपको अर्धविराम की आवश्यकता नहीं है। – vitaut

+1

वास्तव में सवाल का जवाब नहीं दे रहा है, लेकिन यह विशेषज्ञता के बजाए ओवरलोडिंग का उपयोग करने के लिए क्लीनर/आसान नहीं होगा? विशेषज्ञता बनाम अधिक भार पर एक चर्चा के लिए, हर्ब Sutter से इन लेखों देखें: [C/C++ उपयोगकर्ता जर्नल अनुच्छेद] (http://www.gotw.ca/publications/mill17.htm) और [# 49 GotW] (http://www.gotw.ca/gotw/049.htm)। –

+0

@Luc से +1। यदि आप केवल 'शून्य एफ (char c =' a ') {}' करते हैं तो यह पूरी तरह से संकलित करता है। –

उत्तर

21

मुझे लगता है कि की एक स्पष्ट विशेषज्ञता पर अनुमति नहीं है कि इस त्रुटि के पीछे तर्क यह है कि समारोह टेम्पलेट में डिफ़ॉल्ट तर्क करने के लिए लागू की वजह से है इसकी विशेषज्ञता भी है और आपको C++ में एक से अधिक बार डिफ़ॉल्ट तर्क को परिभाषित करने की अनुमति नहीं है।

#include <iostream> 

template<class T> void f(T t = 'a') {} 

template<> void f<char>(char c) 
{ 
    std::cout << c << std::endl; 
} 

int main(int argc, char **argv) 
{ 
    f<char>(); 
} 

यह जिसका अर्थ है कि विशेषज्ञता डिफ़ॉल्ट तर्क मुख्य टेम्पलेट में परिभाषित के साथ कहा जाता है a प्रिंट होगा:

निम्नलिखित पर विचार करें।

आप प्रत्येक विशेषज्ञता के लिए एक अलग डिफ़ॉल्ट तर्क की जरूरत है आप दृष्टिकोण वर्णन नीचे का उपयोग कर सकते हैं:

#include <iostream> 

template<class T> 
struct default_arg 
{ 
    static T get() { return T(); } 
}; 

template<class T> void f(T t = default_arg<T>::get()) {} 

template<> 
struct default_arg<char> 
{ 
    static char get() { return 'a'; } 
}; 

template<> void f<char>(char c) 
{ 
    std::cout << c << std::endl; 
} 

int main(int argc, char **argv) 
{ 
    f<char>(); 
} 
+0

यह बहुत अच्छा नहीं है .. यह कहता है कि सभी प्रकार 'टी' को चार के साथ प्रारंभ करने में सक्षम होना चाहिए .. या एक उचित कास्ट ऑपरेटर को चार में रखना चाहिए। –

+0

@ किरील किरोव: यह बिंदु को चित्रित करने के लिए सिर्फ एक उदाहरण है (क्यों संकलक यह त्रुटि देता है)। – vitaut

+0

हाँ, लेकिन अभी भी .. वैसे भी: +1 - विचार के लिए, संपादित के बाद जोड़ा (:। –

14

सी ++ 98 §12.7/21 "डिफ़ॉल्ट समारोह तर्क में निर्दिष्ट नहीं किया जाएगा ... फ़ंक्शन टेम्पलेट का स्पष्ट विशेषज्ञता "।

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

+0

+1 मानक के प्रासंगिक भाग का हवाला देते हुए के लिए कभी इस पर अच्छा था =) – vitaut

+1

दरअसल, स्पष्ट विशेषज्ञताओं नहीं पाए जाते हैं नाम-लुकअप द्वारा। टेम्पलेट तर्क कटौती फ़ंक्शन टेम्पलेट पर की जाती है, और यदि इसे केवल 'f()' कहा जाता है, तो यह 'टी' को कम नहीं कर सकता है। इसे 'char' चुनना कब होगा।कोई तर्क दे सकता है कि कोई 'एफ () 'और' एफ ' के लिए एक स्पष्ट विशेषज्ञता है जो डिफ़ॉल्ट तर्क प्रदान करता है, इसका उपयोग किया जाएगा। लेकिन मुझे इसके लिए थोड़ा उपयोग दिखाई देता है और यह केवल टेम्पलेट तर्क कटौती को और जटिल करेगा। –

2

जो विशेष टेम्पलेट उदाहरण का उपयोग करने के चयन प्रदान की पैरामीटर के प्रकार पर आधारित है। इस प्रकार स्पष्ट विशेषज्ञता का चयन एक चार तर्क के प्रावधान द्वारा किया जाता है - यह केवल उस बिंदु पर है कि डिफ़ॉल्ट तर्क (जैसा कि आपने कोड किया है) खेल में आ जाएगा (जहां यह अनावश्यक है)।

यह केवल टेम्पलेट घोषणा पर ही डिफ़ॉल्ट तर्क प्रदान करने के लिए समझ में आता है। नुकसान यह है कि आपको उचित विशेषज्ञता स्वयं निर्दिष्ट करना है (जो पहली जगह में डिफ़ॉल्ट तर्क का उपयोग करने में कुछ फायदे हटा देता है)।

व्यवहार है कि (मेरा मानना ​​है कि) आप चाहते हैं को प्राप्त करने, निम्नलिखित का उपयोग करें।

template<class T> void f(T t) {} 

template<> void f<char>(char c) {} 

void f() { f('a'); } 
संबंधित मुद्दे

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