Aarkan
Aarkan

Reputation: 4109

Defining value traits for floating points

while writing some code in c++, I want to express the notion that for a component of type X, its min value is kMinValue and its max value is kMaxValue. For this purpose, I did something like:

template <typename ComponentType>
struct CompTraits
{

};

template <>
struct CompTraits<unsigned char>
{
    typedef unsigned char ComponentType;
    enum{
        kMinValue = 0,
        kMaxValue = 255
    };              
};

And, I can refer CompTraits<unsigned char>::kMinValue. But, I am not able to understand the trick for floating data types. Could someone please help in defining the same thing for floats.

Thanks in advance.

Upvotes: 2

Views: 460

Answers (3)

zakinster
zakinster

Reputation: 10698

You can't used an enum to define those values since an enum can only store integer values, you could use constants instead :

template <>
struct CompTraits<double>
{
    typedef double ComponentType;
    static const double kMinValue = 0.;
    static const double kMinValue = 1.;          
};

Also for standard numeric types you could take a look at the std::numeric_limit of the C++ STL.

numeric_limits<unsigned char>::min() will do the same thing as your CompTraits<unsigned char>::kMinValue, and it's implemented for every numeric types.

Also note that you can specialize numeric_limit for your own data type :

namespace std {
    template<>
    struct numeric_limits<YourType>
    {
        static const bool is_specialized = true;
        /* assuming YourType has a constructor from double */
        static const YourType min() throw() { return 0. };
        static const YourType max() throw() { return 1. };
    };
}

If you have doubt about the legitimacy of this approach, see :

« A program may add template specializations for any standard library template to namespace std. Such a specialization (complete or partial) of a standard library template results in undefined behavior unless the declaration depends on a user-defined name of external linkage and unless the specialization meets the standard library requirements for the original template.» from C++ 2003, §17.4.3.1/1

Upvotes: 1

ForEveR
ForEveR

Reputation: 55897

You can use std::numeric_limits, instead of your constants, but if you want only kMinValue and kMaxValue - you can use something like this

C++03

template<>
struct CompTraits<float>
{
   static const float kMinValue;
   static const float kMaxValue;
};

const float CompTraits<float>::kMinValue = std::numeric_limits<float>::min();
const float CompTraits<float>::kMaxValue = std::numeric_limits<float>::max();

C++11

template<>
struct CompTraits<float>
{
   static constexpr float kMinValue = std::numeric_limits<float>::min();
   static constexpr float kMaxValue = std::numeric_limits<float>::max();
};

for your case you simply should use

template<>
struct CompTraits<float>
{
   static const float kMinValue = 0.0f;
   static const float kMaxValue = 1.0f;
};

Upvotes: 5

Some programmer dude
Some programmer dude

Reputation: 409356

It's because you use enum for the constants. Enumeration constants can only be integers.

I suggest you use static const member variables instead (or static constexpr if you're using a C++11 compiler).

Upvotes: 2

Related Questions