How far to go with a strongly typed language?

If you wanted this simpler approach generalize it so you can get more use out of it, instead of tailor it to a specific thing. Then the question is not “should I make a entire new class for this specific thing?” but “should I use my utilities?”; the latter is always yes. And utilities are always helpful.

So make something like:

template <typename T>
void check_range(const T& pX, const T& pMin, const T& pMax)
{
    if (pX < pMin || pX > pMax)
        throw std::out_of_range("check_range failed"); // or something else
}

Now you’ve already got this nice utility for checking ranges. Your code, even without the channel type, can already be made cleaner by using it. You can go further:

template <typename T, T Min, T Max>
class ranged_value
{
public:
    typedef T value_type;

    static const value_type minimum = Min;
    static const value_type maximum = Max;

    ranged_value(const value_type& pValue = value_type()) :
    mValue(pValue)
    {
        check_range(mValue, minimum, maximum);
    }

    const value_type& value(void) const
    {
        return mValue;
    }

    // arguably dangerous
    operator const value_type&(void) const
    {
        return mValue;
    }

private:
    value_type mValue;
};

Now you’ve got a nice utility, and can just do:

typedef ranged_value<unsigned char, 0, 15> channel;

void foo(const channel& pChannel);

And it’s re-usable in other scenarios. Just stick it all in a "checked_ranges.hpp" file and use it whenever you need. It’s never bad to make abstractions, and having utilities around isn’t harmful.

Also, never worry about overhead. Creating a class simply consists of running the same code you would do anyway. Additionally, clean code is to be preferred over anything else; performance is a last concern. Once you’re done, then you can get a profiler to measure (not guess) where the slow parts are.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)