Mark Ingram
Mark Ingram

Reputation: 73585

Comparing template type to constant number value

Is there a better way of doing the following?

I have a vector class, with the following function:

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

As T can be float or double (I'm using explicit template instantiation to make sure only these types are supported), I've had to create a helper class, which returns the value of 1, in the correct type:

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

This wasn't too bad until I realised I need to create a Zero class as well for other comparisons. So my question is, is there a better way of achieving this?

Upvotes: 5

Views: 229

Answers (3)

James McNellis
James McNellis

Reputation: 354969

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

Small, nonnegative integer values should all be exactly representable by each of the numeric types, so simply static_cast'ing to the desired type should be sufficient.

Alternatively, assuming IsAlmostEqual is a static member function that has two parameters of type T (e.g. as IsAlmostEqual(T lhs, T rhs)), simply let the compiler perform the conversion automatically in the function call:

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

Upvotes: 8

user1773602
user1773602

Reputation:

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

Upvotes: 0

dchhetri
dchhetri

Reputation: 7136

Why not just let the compiler do the conversion work

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

not sure if syntax is correct, but thats the general idea.

Upvotes: 0

Related Questions