2010-12-08 14 views
8

तो मेरे पास है:मैं टेम्पलेट क्लास के स्थिर सदस्यों को कैसे कॉल करूं?

template <class T> 
class A 
{ 
static void f() 
{ 
    // not using template parameter T 
} 
}; 

इस मामले A<int>::f() में A<double>::f() रूप में ही है, लेकिन मैं टेम्पलेट पैरामीटर के माध्यम से A::f() फोन नहीं करना चाहती। क्या कोई वाक्यविन्यास है जो f() पर कॉल करने की अनुमति देता है लेकिन टेम्पलेट पैरामीटर की आवश्यकता नहीं है?

उत्तर

15

संकलक नहीं जानता है कि A<T>::f() प्रकार पैरामीटर T उपयोग नहीं करता। तो जैसा कि है, आप किसी भी समय संकलक को f का उपयोग करने के लिए एक प्रकार देना होगा।

लेकिन जब मैं एक टेम्पलेट वर्ग तैयार कर रहा हूं और मुझे लगता है कि कुछ सदस्य/विधियां टेम्पलेट पैरामीटर पर निर्भर नहीं हैं, तो मैं उन्हें अक्सर गैर-टेम्पलेट बेस क्लास में ले जाऊंगा।

class A_Base { 
public: 
    static void f(); 
}; 

template <class T> class A : public A_Base { 
    // ... 
}; 

अब A_Base::f(), A<int>::f(), और A<double>::f() वास्तव में सभी एक ही बात कर रहे हैं।

+0

साफ कामकाज के लिए +1। हालांकि संकलक को यह पता करने में सक्षम होना चाहिए कि क्या यह पैरामीटर टी का उपयोग करता है - यदि कोड में पहचानकर्ता टी के कोई उदाहरण नहीं हैं तो निश्चित रूप से इसका उपयोग नहीं किया जा रहा है। –

+1

@ बिली: लेकिन यदि कक्षा सार्वजनिक पुस्तकालय का हिस्सा है, तो 'टी' पैरामीटर का उपयोग शुरू करने से एबीआई-ब्रेकिंग परिवर्तन होगा, क्योंकि 'ए :: एफ()' अब मान्य नहीं होगा। कार्यों में सामग्री का परिचय * कभी नहीं, कभी * एबीआई तोड़ना चाहिए, केवल फ़ंक्शन परिभाषा में परिवर्तन होना चाहिए। – cdhowie

+1

@ बिली ओनेल: हाँ, सिवाय जब 'एफ()' कुछ 'ए :: जी() 'को कॉल करता है जो' टी' पर निर्भर करता है। हालांकि, सामान्य नियम यह है कि किसी पहचानकर्ता के उपयोग के संबंध में कुछ भी इसकी घोषणा पर निर्भर होना चाहिए, भाषा 'f ()' 'f()' के साथ समान नहीं है, भले ही 'टी' शरीर में उपयोग नहीं किया जाता है 'एफ ' '। वर्ग संरचना के लिए – jpalecek

1

नहीं - यदि आप टेम्पलेट तर्क का उपयोग नहीं करना चाहते हैं, तो वर्ग को टेम्पलेट पैरामीटर के साथ घोषित न करें। यदि आपको कक्षा के अन्य सदस्यों के लिए टेम्पलेट तर्क की आवश्यकता है, लेकिन इसे f में इसकी आवश्यकता नहीं है, तो कक्षा के बाहर f स्थानांतरित करें।

0

नहीं, वास्तव में A<int>::f()A<any_other_type>::f() जैसा नहीं है। वे वास्तव में अलग हैं। आप f() चाहते हैं पैरामीटर का वास्तव में स्वतंत्र होने के लिए, आप टेम्पलेट वर्ग A अन्य वर्ग (कभी कभी एक विशेषता कहा जाता है) कि एक स्थिर सदस्य समारोह के रूप में f() प्रदान करता है से विरासत के लिए कर सकते हैं:

struct X 
{ 
    static void f() { ...} 
}; 

template <typename T> 
struct A : X 
{ 
    ... 

फिर, आप कर सकते हैं A<type>::f() या X::f() पर कॉल करें।

2
  1. निर्दिष्ट करने के लिए कोई वाक्यविन्यास नहीं है। f वैसे भी एक स्थिर विधि बनाने के लिए बहुत कम कारण है। इसके बजाय इसे एक मुफ्त समारोह बनाओ। यदि आपको किसी कारण से इसे स्थैतिक विधि बनाना है, तो इसे एक मुक्त फ़ंक्शन के संदर्भ में लागू करें और केवल इसे कॉल करें।
  2. कई कंपाइलर्स शायद आपके लिए यह स्वचालित रूप से करेंगे।
+0

मैं मुक्त स्थिर समारोह का उपयोग नहीं कर सकते हैं, क्योंकि यह मेरा कोड नहीं है, मैं बस पहले ही लिखित एपीआई का उपयोग कर रहा हूं। उत्तर के लिए बहुत बहुत धन्यवाद :) –

+0

@ मिहरान: हुह? एक एपीआई एक स्थिर विधि के बारे में कैसे देखभाल कर सकते हैं? * श्वास * (बिल स्मैश स्ट्रैंज एपीआई! :)) –

1

निश्चित रूप से। इसे फ़ंक्शन पॉइंटर को असाइन करके इसे उपनाम दें।

+1

बेशक, आपको अभी भी उस टाइपर को प्रारंभ करने के लिए एक विशिष्ट प्रकार का "उपयोग" करने की आवश्यकता होगी, जैसे 'typedef void (* func_ptr)(); func_ptr ए_एफ = और ए :: एफ; ' – aschepler

0

के चारों ओर एक cludgy काम (आप विरासत का उपयोग नहीं करना चाहते हैं और आप यह एक गैर सदस्य समारोह बनाने के लिए नहीं करना चाहते हैं), तो आपको एक डिफ़ॉल्ट प्रकार अपने वर्ग के लिए निर्दिष्ट कर सकते हैं:

template <class T = bool> 
class A 
{ 
    public: 
    static void f() { cout << "f()" << endl; } 
}; 

int main(void) 
{ 
    A<>::f(); 
    return 0; 
} 

नोट: इस विधि हालांकि समान नहीं है, A<int>::f() या A<long>::f() आदि के रूप में, लेकिन यदि आप समारोह में कोई प्रकार निर्भरता है - तो ऊपर काम कर सकता था ...

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

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