2012-11-22 16 views
5

प्राप्त करने के लिए टेम्पलेट पैरामीटर के नेस्टेड टाइपपीफ की जांच करें, नीचे घातीय चिकनी टेम्पलेट वर्ग पर विचार करें। यह वर्ग क्रमिक रूप से अनुक्रमिक डेटा को चिकनाई/फ़िल्टर करने के लिए है (अद्यतन विधि देखें)। एलेमटाइप एक वेक्टर हो सकता है और फ्लोटटाइप आमतौर पर एक स्केलर होता है। जैसेसी ++ अपने स्केलर बेस प्रकार

ExponentialSmoother<Eigen::Vector2f, float> x(0.1, Vector2f(0.5, 0.5)); 

इस उदाहरण में दूसरा टेम्पलेट पैरामीटर Floattype बचा जा सकता है क्योंकि Eigen के मैट्रिक्स वर्ग एक नेस्टेड typedef अदिश आधार प्रकार प्राप्त करने के लिए शामिल हैं:

Vector2f::Scalar 

यह भी दोनों Elemtype और Floatype का दृष्टांत करने के लिए उचित है एक आयामी डेटा को सुचारू बनाने के लिए तैरता है। इस मामले में दूसरा टेम्पलेट पैरामीटर भी छोड़ा जा सकता है।

template <class Elemtype, class Floattype> 
class ExponentialSmoother 
{ 
public: 
    // ctor 
    ExponentialSmoother(Floattype alpha, Elemtype& initial_estimate); 

    // getters 
    inline const Elemtype& getValue() const {return estimate_;} 
    inline const Floattype getAlpha() const {return alpha_;} 

    const Elemtype& update(const Elemtype& curr) 
    { 
     estimate_ = (alpha_ * curr) + (((Floattype)1-alpha) * estimate_); 
     return estimate_; 
    } 

private: 
    Elemtype estimate_; 
    Floattype alpha_; // smoothing factor within [0,1] 
} 

अब मेरे सवाल का क्या केवल एक टेम्पलेट पैरामीटर (तत्व प्रकार) के साथ ExponentialSmoother लागू करने के लिए "सबसे खूबसूरत" समाधान है? इसे ईजिन वैक्टर और मैट्रिस के साथ काम करना चाहिए, लेकिन फ्लोटिंग पॉइंट प्रकारों के साथ भी काम करना चाहिए।

दूसरे शब्दों में, क्या यह जांचना संभव है कि Elemtype :: Scalar मौजूद है और यदि नहीं (यानी Elemtype फ्लोट या डबल है) फ़्लैटाइप को एल्मटाइप के रूप में परिभाषित करता है?

एक समान प्रश्न पूछा गया है here। लेकिन मैं सोच रहा हूं कि सबसे सामान्य समाधान क्या है यदि उदाहरण के लिए एसटीएल वैक्टरों को भी समर्थन दिया जाना चाहिए। क्या सभी प्रकारों को एक ही नेस्टेड टाइपपीफ (या लगातार नामकरण वाले कुछ लक्षण वर्ग) की आवश्यकता होगी?

+0

* क्या सभी प्रकारों को एक ही नेस्टेड टाइपपीफ (या लगातार नामकरण वाले कुछ लक्षण वर्ग) की आवश्यकता होगी? * - हाँ। –

उत्तर

3

आप एक सहायक का उपयोग कर सकते हैं।

template<class T, class R = void> 
struct enable_if_type 
{ 
    typedef R type; 
}; 

template<class E, class Enable = void> 
struct GetFloatType 
{ 
    typedef E type; 
}; 

template<class E> 
struct GetFloatType<E, typename enable_if_type<typename E::Scalar>::type> 
{ 
    typedef typename E::Scalar type; 
}; 

फिर, अपनी कक्षा में:, के साथ इस उपयोगकर्ताओं को अब भी मैन्युअल रूप से उनकी नाव प्रकार प्रदान कर सकते हैं

template <class Elemtype, class Floattype = typename GetFloatType<Elemtype>::type> 
class ExponentialSmoother 
{ 
    // ... 
}; 

भी लिंक दिया था लगभग समाधान में शामिल है। आप इसे live देख सकते हैं। बोनस: समस्याओं के बिना सी ++ 03 के साथ काम करता है।

ध्यान दें कि आप GetFloatType के अधिक आंशिक विशेषज्ञता जोड़ सकते हैं। Here is a live example। यह मत भूलना कि ElemType को के लिए स्वीकार्य होना चाहिए केवलGetFloatType का विशेषज्ञता, या अन्यथा यह संदिग्ध होगा (और एक कंपाइलर त्रुटि का कारण बन जाएगा)।

+0

धन्यवाद, यह वास्तव में एक बहुत ही सुरुचिपूर्ण समाधान है। अब यदि मैं अन्य मैट्रिक्स प्रकारों का समर्थन करना चाहता हूं तो मैं मूल रूप से अधिक टेम्पलेट विशेषज्ञता जोड़ सकता हूं, उदाहरण के लिए: 'टेम्पलेट संरचना GetFloatType :: type> {...} .' – spinxz

+0

हां, आप और विशेषज्ञता जोड़ सकते हैं। मेरा संपादन देखें (उत्तर का अंत)। – Synxis

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