2012-11-22 37 views
5

考慮下面的指數平滑模板類。該類用於按指數順序平滑/過濾順序數據(請參閱更新方法)。 Elemtype可能是一個矢量,Floattype通常是一個標量。例如。C++檢查模板參數的嵌套typedef以獲得其標量基類型

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

在這個例子中,第二個模板參數可避免Floattype因爲本徵的Matrix類包含嵌套的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是float還是double),則將Floattype定義爲Elemtype?

一個類似的問題已被要求here。但是我想知道什麼是最通用的解決方案,例如STL向量也應該被支持。所有類型都需要相同的嵌套typedef(或者一些具有一致命名的特徵類)?

+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 
{ 
    // ... 
}; 

此外,對於該用戶仍然可以手動提供他們的float類型。你可以看到它live。獎金:適用於C++ 03,沒有任何問題。

請注意,您可以添加更多的GetFloatType偏特。 Here is a live example。不要忘那ElemType必須爲GetFloatType只有一個專業化是可以接受的,否則就會產生歧義(並且導致編譯器錯誤)。

+0

謝謝,這確實是一個非常優雅的解決方案。 現在,如果我想支持其他矩陣類型,我基本上可以添加更多的模板特化,例如: 'template struct GetFloatType :: type> {...} .' – spinxz

+0

是的,你可以添加更多的專業化。看我的編輯(答案的結尾)。 – Synxis