6

以下の指数関数的で滑らかなテンプレートクラスについて考えてみます。このクラスは、順次データを指数関数的に平滑化/フィルタリングするためのものです(updateメソッドを参照)。Elemtypeはベクトルであり、Floattypeは通常スカラーです。例えば

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

この例では、EigenのMatrixクラスにスカラー基本型を取得するためのネストされたtypedefが含まれているため、2番目のテンプレートパラメーターFloattypeを回避できます。

Vector2f::Scalar

ElemtypeとFloatypeの両方をfloatとしてインスタンス化して、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]
}

ここで私の質問は、1つのテンプレートパラメーター(要素タイプ)のみでExponentialSmootherを実装するための「最もエレガントな」ソリューションは何ですか?固有ベクトルと行列だけでなく、浮動小数点型でも機能するはずです。

言い換えると、Elemtype :: Scalarが存在するかどうかを確認し、存在しない場合(つまり、Elemtypeがfloatまたはdoubleである)、FloattypeをElemtypeとして定義することは可能ですか?

同様の質問がここで行われました。しかし、たとえばSTLベクトルもサポートする必要がある場合、最も一般的な解決策は何でしょうか。すべてのタイプに同じネストされたtypedef(または一貫した名前のいくつかのトレイトクラス)が必要ですか?

4

1 に答える 1

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

また、この場合でも、ユーザーは手動でフロートタイプを指定できます。あなたはそれをライブで見ることができます。ボーナス:C++03で問題なく動作します。

の部分的な特殊化をさらに追加できることに注意してくださいGetFloatTypeこれが実際の例です。の1つの特殊化に対してのみElemType受け入れられる必要があることを忘れないでください。そうしないと、あいまいになります(そしてコンパイラエラーが発生します)。GetFloatType

于 2012-11-22T17:48:33.787 に答える