2012-02-16 14 views
7

अगर मैं इतना स्पष्ट हूं तो उत्तर पाने के लिए पर्याप्त बेवकूफ हूं, तो मैं क्षमा चाहता हूं।सी ++: टेम्पलेट को विशेषज्ञ बनाने के लिए टेम्पलेट को कैसे रोकें?

मैंने सूचक पैरामीटर के लिए विशिष्ट टेम्पलेट विशेषज्ञता रखने के बारे में बात करने वाले दर्जनों पृष्ठों को देखा है।

हालांकि, मैं सूचक मानकों को विशेषज्ञता देने के लिए टेम्पलेट को रोकने में सक्षम होना चाहता हूं, लेकिन मैं यह नहीं समझ सकता कि यह कैसे करें।

template< class T > 
void function(T arg) 
{ 
    //... 
} 

int main() 
{ 
    int i = 42; 

    function(i); // Ok 
    function(&i); // Die bastart with a compiler error! 
} 

क्या यह संभव है?

धन्यवाद।

+1

जब आपके पास सी ++ 11 तक पहुंच है, तो आप केवल static_assert – PlasmaHH

+1

का उपयोग कर सकते हैं, यह 'टेम्पलेट ' नहीं होना चाहिए? – Jacob

+0

@ जैकोब: अभी तय किया गया है। – MSalters

उत्तर

14

आप विशेषज्ञता घोषणा कर सकते हैं (इस मामले में यह तकनीकी रूप से सिर्फ एक अधिभार है), लेकिन नहीं इसे परिभाषित :)

template<typename T > 
void function(T arg) 
{ 
//... 
} 

template<typename T > 
void function(T* arg); //no definition 

int main() 
{ 
    int i = 42; 
    function(i); // Ok 
    function(&i); //ERROR 
} 
+0

क्या यह एक लिंकर त्रुटि या संकलन त्रुटि है? –

+4

@ daknøk: यह एक कंपाइलर त्रुटि है, क्योंकि यह एक टेम्पलेट है। टेम्पलेट की परिभाषा एक ही अनुवाद इकाई (स्रोत फ़ाइल) में होनी चाहिए। लिंकर टेम्पलेट्स के बारे में कुछ भी नहीं जानता है। कंपाइलर टेम्पलेट इंस्टेंटेशन के लिए ज़िम्मेदार है, और यह परिभाषा –

+0

+1 हां के बिना ऐसा नहीं कर सकता है, ज़ाहिर है, यह आसान है! मैं हमेशा इसे कठिन तरीके से क्यों करना चाहता हूं? –

6

मैं अपने आप को एक टेम्पलेट metaprogramming रूकी हूँ, लेकिन मुझे लगता है कि

template<typename T> 
void function(typename std::enable_if<!std::is_pointer<T>::value,T>::type arg) 
{ 
    //... 
} 

काम करना चाहिए, क्योंकि यह फ़ंक्शन केवल गैर-सूचक पैरामीटर के लिए मौजूद होना चाहिए। बेशक इसके लिए सी ++ 11 या कम से कम टीआर 1 या बूस्ट के प्रकार के लक्षणों की आवश्यकता होती है।

+0

+1 मैं एक विकल्प का परीक्षण कर रहा था (कि मैं थोड़ा और अधिक उपयोग कर रहा हूं): 'टेम्पलेट टाइपनाम सक्षम_आईफ़ :: value> :: प्रकार फ़ंक्शन (टी तर्क)', लेकिन आपका भी काम करना चाहिए। (और लिंकर त्रुटियों के बजाय दोनों ट्रिगर * कंपाइलर * त्रुटियां) –

7

सी ++ 11 में, आप इस तरह एक तरह से static_assert उपयोग कर सकते हैं:

template<class T> 
void func(T arg) { 
    static_assert(!std::is_pointer<T>::value, 
       "The argument to func must not be a pointer."); 
    // Do something after the static_assert. 
    // Now you are sure that T isn't a pointer. 
} 

एक उदाहरण here on Ideone पाया जा सकता है।

मैं इसकी अनुशंसा करता हूं क्योंकि जब कोई व्यक्ति आपके फ़ंक्शन को पॉइंटर से कॉल करने का प्रयास करता है तो यह अधिक उपयोगी त्रुटि संदेश देगा (लिंकर त्रुटियां इस मामले में बहुत भ्रमित हो सकती हैं)। साथ ही, लिंक होने से पहले लिंकर त्रुटियां दिखाई नहीं देगी।

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