2012-11-22 4 views
5

以下の指数関数的なスムーサーテンプレートクラスを考えてみましょう。このクラスは、順次データを指数関数的に平滑化/フィルタリングするためのクラスです(updateメソッドを参照)。 Elemtypeはベクトルで、Floattypeは通常スカラーです。例えば。固有のMatrixクラスは、スカラ基本型を取得するには、ネストされたのtypedefが含まれているためC++テンプレートパラメータのネストされたtypedefを調べてスカラー基本型を取得する

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

この例では、第二のテンプレートパラメータFloattypeを避けることができます。

Vector2f::Scalar 

またElemtypeとFloatypeの両方をインスタンス化するのが妥当です1次元のデータを滑らかにするための浮動小数点数です。この場合、第2のテンプレートパラメータもスキップすることができる。

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か)、FloatypeをElemtypeとして定義できますか?

同様の質問がhereと尋ねられました。しかし、私は、例えばSTLベクターも同様にサポートされるべきであるなら、最も一般的な解決策が何であるか疑問に思います。すべての型に同じネストされたtypedef(または一貫した命名規則を持ついくつかのtraitsクラス)​​が必要でしょうか?

+0

*すべての型は、同じネストされたtypedef(または一貫した命名規則を持ついくつかの特性クラス)を必要としますか?* - はい。 –

答えて

3

ヘルパーを使用できます。このユーザはまだ手動でfloat型を提供することができますし、また

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

:あなたのクラスで次に

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; 
}; 

、:あなたが与えたリンクは、ほとんどソリューションが含まれています。あなたはliveを見ることができます。ボーナス:C++ 03で問題なく動作します。

GetFloatTypeの部分的な特殊化を追加できます。 Here is a live exampleElemTypeは、のうち1つだけの修飾GetFloatTypeを受け入れなければならないことを忘れないでください。さもなければ、それはあいまいであり(コンパイラエラーの原因となります)。

+0

ありがとう、これは確かに非常にエレガントなソリューションです。 他のMatrix型をサポートしたい場合は、基本的にテンプレート特殊化を追加することができます: 'template 構造体GetFloatType {型} – spinxz

+0

はい、さらにスペシャライゼーションを追加できます。私の編集(答えの終わり)を参照してください。 – Synxis

関連する問題