2012-11-02 6 views
5

以下のより良い方法がありますか?テンプレートの型と定数の値の比較

私は次の関数で、ベクトルクラスを持っている:

template <typename T> 
bool Vector3<T>::IsUnitVector() const 
{ 
    return IsAlmostEqual(this->GetLength(), One<T>::Value()); 
} 

Tがfloatまたはdouble(私は、これらのタイプがサポートされていることを確認するために、明示的なテンプレートのインスタンスを使用しています)、私はきたことができるように正しいタイプで、1の値を返すヘルパークラスを作成する必要がありました:私は、私は他の比較のためにもZeroクラスを作成する必要が実現するまで

template <typename T> 
struct One 
{ 
    static T Value(); 
}; 

template <> 
struct One<int> 
{ 
    static int Value() { return 1; } 
}; 

template <> 
struct One<float> 
{ 
    static float Value() { return 1.0f; } 
}; 

template <> 
struct One<double> 
{ 
    static double Value() { return 1.0; } 
}; 

これはそれほど悪くはなかったです。だから私の質問は、これを達成するためのより良い方法はありますか?

+1

これは非常に一般的だと思います。 'One 'の非特化版で 'return 1;'と言うだけですか?私はこれが暗黙の変換のおかげでそれを行うと思います。 – leemes

+0

私はしましたが、IsAlmostEqualがテンプレート化されているため、コンパイラはどのタイプを使うべきかわかりません(intはfloat、doubleなどに変換できるため)。 –

答えて

8
return IsAlmostEqual(this->GetLength(), static_cast<T>(1)); 

小型、非負整数値は、すべての所望のタイプにINGの単にstatic_cast」が十分でなければならない、数値型のそれぞれによって正確に表現可能であるべきです。あるいは

、単にコンパイラは、関数呼び出しで自動的に変換を実行でき、IsAlmostEqualは(IsAlmostEqual(T lhs, T rhs)として例えば)タイプTの2つのパラメータを有する静的メンバ関数であると仮定すると:

return IsAlmostEqual(this->GetLength(), 1); 
+0

暗黙の変換は機能しません。これは、コンパイラから曖昧な型Tエラーが発生するためです。 static_castはうまくいくはずです! –

+0

回答が受け入れられました - 'static_cast '提案のため。ありがとう! –

0

理由だけせませんコンパイラは変換作業を行います。

template<typename T, int val> 
bool Vector3<T>::_isConstant()const{ 
    return IsAlmostEqual(this->GetLength(), val); 
} 

template <typename T> 
bool Vector3<T>::IsUnitVector() const{ 
    return _isConstant<T,1>(); 
} 
template<typename T> 
bool Vector3<T>::IsZeroVector()const{ 
    return _isConstant<T,0>(); 
} 

構文が正しいかどうかはわかりませんが、一般的な考え方です。

0
template <typename T> 
struct Value 
{ 
    static T Zero(); 
    static T One(); 
}; 

template <> 
struct Value<int> 
{ 
    static int Zero() { return 0; } 
    static int One() { return 1; } 
}; 
// .. and so on 
関連する問題