2012-11-02 20 views
5

有没有更好的方法来完成以下工作?将模板类型与常数值比较

我有一个载体类,具有以下功能:

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

由于T可以是浮动或双(我使用显式模板实例化,以确保只有这些类型的支持),我已经必须创建一个辅助类,它返回值1,在正确的类型:

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

这是不是太糟糕,直到我意识到我需要创建一个Zero类以及其他的比较。所以我的问题是,有没有更好的方法来实现这一目标?

+1

我觉得这很常见。你是否试图在“One ”的非专业版本中说'return 1;'?我认为这会通过隐式转换来实现。 – leemes

+0

我做了,但因为IsAlmostEqual是模板化的,所以编译器不知道要使用哪种类型(因为int可以转换为float,double等)。 –

回答

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

小,非负整数的值应全部是由每个数字类型的精确表示,所以简单地static_cast“荷兰国际集团为所需的类型应该是足够的。

可替换地,假设IsAlmostEqual是具有T类型(例如,如IsAlmostEqual(T lhs, T rhs))的两个参数的静态成员功能,只需让编译器在函数调用自动执行转换:

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