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?
Edit
std::less_equal and std::greater_equal both inherit from std::binary_function (hence the title of my question), so I tried this:
template<typename T, typename _Compare_func = std::less_equal<T>, typename std::enable_if<std::is_arithmetic<T>::value || std::is_same<std::binary_function<T, T, bool>, _Compare_func>::value>::type* = nullptr>
class Threshold
{
public:
...
};
but that didn't seem to make a difference.
CodePudding user response:
You specifically declared foo as a function that only takes a Threshold<T>
, i.e. an instance of a template where the comparator is the default. Just include both template arguments in your definition:
template<typename T, typename comp_func,
typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
void foo(Threshold<T, comp_func>& threshold)
{
// . . .
}