samedi 22 octobre 2022

How to create a template that can use different arguments from the same base class

I'm trying to create a Threshold template class that allows me to compare numeric values against a threshold value. I want to easily change the comparison function to use greater_equal or less_equal so I create the following template:

template<typename T, typename comp_func = std::greater_equal<T>, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
class Threshold
{
public:
    Threshold(T threasholdValue) : _thresholdValue(threasholdValue) {}
    ~Threshold() = default;

    bool isExceeded(T value) const
    {
        return comp_func{}(value, _thresholdValue);
    }

private:
    T _thresholdValue;
};

I want to be able to pass instances of this class to a function that accepts the Threshold:

template<typename T, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
void foo(Threshold<T>& threshold)
{
. . .
}

This works fine as long as I use the default comparison function (std::greater_equal) but when I try to create a Threashold with "std::less_equal", this becomes a different type and I cannot pass it into foo:

Threshold<int32_t> greaterEqThreshold(5);
Threshold<int32_t, std::less_equal<int32_t>> lessEqThreshold(10);

foo(greaterEqThreshold);
foo(lessEqThreshold);  <--- Compile Error!

I understand why this is happening but I can't figure out how to solve the problem, other by creating a pure virtual class and having Threshold inherit from it and then using reference to that class. However, this solutions seems a little long winded for what I want do do.

Is there a way to make this work? Is there a better way to do this?

Aucun commentaire:

Enregistrer un commentaire