What is the correct way to perform == and != operators in template classes? Assume this code:
template<typename T>
class C {
T x, y;
public:
C(T a, T b) : x(a), y(b) {}
bool cmp() {
return x == y;
}
};
int main()
{
// OK
C<int> i(1,2);
i.cmp();
// not OK
C<double> d(1.0, 2.0);
d.cmp();
return 0;
}
If you build it with g++ -Wfloat-equal, you'll get
warning: comparing floating point with == or != is unsafe [-Wfloat-equal]
because you can't simply compare float variables.
Update
I've solved the problem using type_traits and enable_if like this (thanks @Andrew and @OMGtechy):
#include <type_traits>
#include <limits>
#include <cmath>
#include <iostream>
using namespace std;
template <typename IntegralType>
typename std::enable_if<std::is_integral<IntegralType>::value, bool>::type
equal(const IntegralType& a, const IntegralType& b) {
return a == b;
}
template <typename FloatingType>
typename std::enable_if<std::is_floating_point<FloatingType>::value, bool>::type
equal(const FloatingType& a, const FloatingType& b) {
return std::fabs(a-b) < std::numeric_limits<FloatingType>::epsilon();
}
template<typename T>
class C {
T x, y;
public:
C(T a, T b) : x(a), y(b) {}
bool cmp() {
return equal(x, y);
}
};
int main()
{
// OK
C<int> i(1,2);
cout << i.cmp() << endl;
// not OK
C<double> d(1.0, 1.0);
cout << d.cmp() << endl;
return 0;
}
operator==
, consider added a argument to the template that is the comparator to be used (and then have the default bestd::equal_to
) – Shiah==
is perfectly fine with floating point. For others, checking for near values is correct. – Quintile