2010-10-16 16 views
6

कहें कि मेरे पास निम्न वर्ग है:टेम्पलेट प्रकार पर टेम्पलेट क्लास के स्थिर सदस्य को मैं कैसे विशेषज्ञता दूं?

template<class T> 
struct A 
{ 
    static int value; 
}; 

template<class T> 
int A<T>::value = 0; 

मैं A::value को किसी ठोस प्रकार पर बिना किसी समस्या के विशेषज्ञ कर सकता हूं:

struct B 
{ 
}; 

template<> 
int A<B>::value = 1; 

मैं टेम्पलेट प्रकार पर A :: मान को विशेषज्ञ बनाना चाहता हूं, मैंने कोशिश की निम्न:

template<class T> 
struct C 
{ 
}; 

// error: template definition of non-template 'int A<C<T> >::value' 
template<> 
template<class T> 
int A<C<T> >::value = 2; 

क्या ऐसा करने का कोई तरीका है या क्या गैर-टेम्पलेट प्रकारों पर ए :: मान को विशेषज्ञता देना संभव है?

उत्तर

7

एक पूरी स्पष्ट विशेषज्ञता शुरू करने की बजाय, आप बस प्रारंभ

template<class T> 
struct Value { 
    static int const value = 0; 
}; 

template<class T> 
struct Value< C<T> > { 
    static int const value = 2; 
}; 

template<class T> 
int A<T>::value = Value<T>::value; 
विशेषज्ञ सकता
+0

+1: आपका मतलब हो सकता है मूल्य :: मूल्य। – Chubsdad

+0

@Chubsdad यह ओपी के ए :: मान की परिभाषा है। Vaue :: मूल्य को परिभाषा की आवश्यकता नहीं है। –

2

आप सी के माध्यम से एक का आंशिक विशेषज्ञता का उपयोग कर सकते हैं: एक टेम्पलेट टेम्पलेट तर्क के माध्यम से

#include <iostream> 

using namespace std; 

template<class T> 
struct A 
{ 
    static int value; 
}; 

template<class T> 
int A<T>::value = 0; 

//(1) define the C template class first: 
template<class T> 
struct C 
{ 
}; 

//(2) then define the partial specialization of A, in terms of C: 
template<typename T> 
struct A<C<T> > 
{ 
    static int value; 
}; 

template<typename T> 
int A<C<T> >::value = 2; 

int main(void) 
{ 
    cout<<A<C<int> >::value<<endl; 

    cout<<"ok!"<<endl; 
    return 0; 
} 
+0

यह काम करता है, लेकिन मेरे द्वारा स्वीकार किए गए उत्तर के रूप में लचीला नहीं है। मैं कक्षा ए को अन्य उपयोगकर्ता परिभाषित प्रकारों के लिए विस्तारित करना चाहता हूं, और इसके साथ में मुझे ए का उपयोग करने से पहले परिभाषित ए की सभी विशेषज्ञताएं होंगी, बजाय कहीं भी वैल्यू के विशेषज्ञों को परिभाषित करने में सक्षम होने और लिंकर को काम करने की अनुमति देने की आवश्यकता होगी। –

+0

ठीक है, अगर मुझे आपकी बात सही तरीके से मिलती है, तो आप (समझदारी से) ए को पूर्व-मौजूद टेम्पलेट परिभाषाओं के विशेषज्ञों को टाई नहीं करना चाहते हैं, और प्रत्येक बार जब आप एक नया टाइपनाम नाम परिभाषित करते हैं तो एक नया नया विशेषज्ञता प्रदान करते हैं, जैसे सी, पैरामीटर द्वारा एक टेम्पलेट तर्क। इसका एक समाधान टेम्पलेट-टेम्पलेट तर्क के माध्यम से आंशिक विशेषज्ञता का उपयोग करना है (मेरे दूसरे उत्तर के नीचे देखें)। उम्मीद है की वो मदद करदे। –

0

आंशिक विशेषज्ञता (ऊपर मेरी टिप्पणी देखें):

#include <iostream> 

using namespace std; 

template<class T> 
struct A 
{ 
    static int value; 
}; 

template<class T> 
int A<T>::value = 0; 



//solution 2: 
//define a template-template argument partial specialization 
//for any generic class U depending on a template argument, 
//(which is a typename, in this case, but there's no reason why 
//you wouldn't define specializations for non-types, etc.) 
//this specialization has the advantage of not depending on 
//the template definition of U (or C, etc.); in this case 
//both T and U are free to vary, with the only constraint 
//that U is parameterized by T: 
template<typename T, template<typename> class U> 
struct A<U<T> > 
{ 
    static int value; 
}; 

template<typename T, template<typename> class U> 
int A<U<T> >::value = 3; 

//define the C template class, somewhere, where/when/if needed 
//possibly in a different namespace, "module" (etc.) 
template<class T> 
struct C 
{ 
}; 

int main(void) 
{ 
    cout<<A<C<int> >::value<<endl;//this now should print out: 3 

    cout<<"ok!"<<endl; 
    return 0; 
} 
संबंधित मुद्दे