C++03
The following trick works and it can be used for all such operators:
namespace CHECK
{
class No { bool b[2]; };
template<typename T, typename Arg> No operator== (const T&, const Arg&);
bool Check (...);
No& Check (const No&);
template <typename T, typename Arg = T>
struct EqualExists
{
enum { value = (sizeof(Check(*(T*)(0) == *(Arg*)(0))) != sizeof(No)) };
};
}
Usage:
CHECK::EqualExists<A>::value;
The 2nd template typename Arg
is useful for some special cases like A::operator==(short)
, where it's not similar to class
itself. In such cases the usage is:
CHECK::EqualExists<A, short>::value
// ^^^^^ argument of `operator==`
Demo.
C++11
We need not use sizeof
and null reference trick when we have decltype
and std::declval
namespace CHECK
{
struct No {};
template<typename T, typename Arg> No operator== (const T&, const Arg&);
template<typename T, typename Arg = T>
struct EqualExists
{
enum { value = !std::is_same<decltype(std::declval<T>() < std::declval<Arg>()), No>::value };
};
}
Demo
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…