2017-10-28 9 views
9

मैं वर्तमान में टेम्पलेट्स के साथ संघर्ष कर रहा हूँ निकालें: मैं एक टेम्प्लेटेड वर्ग A है, जो बुनियादी गणित करता है (तैरता के लिए, युगल, जटिल संख्या) है और इस तरहअनावश्यक टेम्पलेट प्रकार

template <typename T> 
class A 
{ 
public: 
    void foo(std::vector<std::complex<T>>& result); 
}; 

अब मैं उपयोग कर सकते हैं लग रहा है A<double>, A<float> जैसी कक्षा, लेकिन मैं इसे A<std::complex<float>> और A<std::complex<double>> जैसे उपयोग करना चाहूंगा। बाद का उपयोग कर, मैं foo की परिभाषा की तरह

void foo(std::vector<std::complex<float>>& result); 

और नहीं देखना चाहते

void foo(std::vector<std::complex<std::complex<float>>>& result); 

वहाँ std::complex<T> मामलों के लिए एक विशेष खाका बनाने के लिए कोई तरीका है चाहते हैं, जिसमें मैं कर सकते हैं "आंतरिक" प्रकार का उपयोग करें? या यह संभव/बुरा अभ्यास नहीं है? इस मुद्दे को हल करने का सबसे शानदार तरीका क्या है?

उत्तर

5

एक और तरीका है

template <typename T> 
struct getFloatType 
{ using type = T; }; 

template <typename T> 
struct getFloatType<std::complex<T>> 
{ using type = T; }; 

(जब जरूरत, उद्धरण) पता लगाने के लिए एक प्रकार का लक्षण के सृजन के माध्यम से पारित कर सकते हैं नाव के प्रकार और A में इसका इस्तेमाल करते हैं (देखें fT)

template <typename T> 
class A 
{ 
    public: 
     using fT = typename getFloatType<T>::type; 

     void foo(std::vector<std::complex<fT>>& result) 
     { } 
}; 
+0

क्या ये दो तरीके बराबर हैं, या उनमें से एक ऐसा करने का पसंदीदा तरीका है? – FlashTek

+0

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

+0

@ फ्लैशटेक यदि आप सिर्फ 'foo' के हस्ताक्षर को बदलना चाहते हैं तो यह एक आसान है। आंशिक विशेषज्ञता के साथ आप अधिक चीजों को कस्टमाइज़ कर सकते हैं, लेकिन जैसा कि आपने पूछा था कि आपको प्राथमिक टेम्पलेट और आंशिक विशेषज्ञता के बीच डुप्लिकेट कोड को संभालना होगा। – songyuanyao

2

std::complex के किसी भी तत्कालता के लिए आप partial specialization बना सकते हैं, उदा।

template <typename T> 
class A<std::complex<T>> 
{ 
public: 
    void foo(std::vector<std::complex<T>>& result); 
}; 

फिर A<std::complex<double>> के लिए, foo के हस्ताक्षर void foo(std::vector<std::complex<double>>& result); होगा।

उन डुप्लिकेट कोडों को संभालने के लिए, आप बेस क्लास बना सकते हैं और आम सदस्यों को इसमें स्थानांतरित कर सकते हैं, और प्राथमिक टेम्पलेट और आंशिक विशेषज्ञता दोनों इसे प्राप्त कर सकते हैं। जैसे

class Base { 
public: 
    void bar(...); 
}; 

तो

template <typename T> 
class A : public Base { 
    ... 
}; 

template <typename T> 
class A<std::complex<T>> : public Base { 
    ... 
}; 
+0

मान लीजिए कि मेरे पास 'ए' कक्षा के अंदर अन्य कार्य हैं, क्या मुझे इन्हें आंशिक विनिर्देशन में परिभाषाएं जोड़ने की ज़रूरत है? – FlashTek

+0

@ फ्लैशटेक हां। आप आधार वर्ग बना सकते हैं और आम सदस्यों को इसमें स्थानांतरित कर सकते हैं, और प्राथमिक टेम्पलेट और आंशिक विशेषज्ञता दोनों इसे प्राप्त कर सकते हैं। – songyuanyao

+0

जब मैं एक शीर्षलेख के अंदर फ़ंक्शन घोषित करता हूं, और इसे शरीर/सीपीपी में परिभाषित करता हूं, तो क्या मैं कोड का पुन: उपयोग कर सकता हूं, या क्या मुझे दो बार सीपीपी के अंदर परिभाषा जोड़ने की आवश्यकता है? – FlashTek

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